Zelda Classic Coverage Report


Directory: src/
File: src/guys.cpp
Date: 2022-12-11 07:24:38
Exec Total Coverage
Lines: 2897 11686 24.8%
Functions: 153 424 36.1%
Branches: 2226 14568 15.3%

Line Branch Exec Source
1 //--------------------------------------------------------
2 // Zelda Classic
3 // by Jeremy Craner, 1999-2000
4 //
5 // guys.cc
6 //
7 // "Guys" code (and other related stuff) for zelda.cc
8 //
9 //--------------------------------------------------------
10
11 #include "precompiled.h" //always first
12
13 #include <string.h>
14 #include <stdio.h>
15 #include "base/zc_alleg.h"
16 6 #include "guys.h"
17 #include "zelda.h"
18 #include "base/zsys.h"
19 #include "maps.h"
20 #include "hero.h"
21 #include "subscr.h"
22 #include "ffscript.h"
23 #include "gamedata.h"
24 #include "defdata.h"
25 #include "zscriptversion.h"
26 #include "particles.h"
27 #include "base/zc_math.h"
28 #include "slopes.h"
29 extern particle_list particles;
30
31 extern FFScript FFCore;
32 extern word item_doscript[256];
33 extern refInfo itemScriptData[256];
34 extern int32_t item_stack[256][MAX_SCRIPT_REGISTERS];
35 extern ZModule zcm;
36 extern HeroClass Hero;
37 extern sprite_list guys, items, Ewpns, Lwpns, Sitems, chainlinks, decorations;
38 extern zinitdata zinit;
39
40 int32_t repaircharge=0;
41 bool adjustmagic=false;
42 bool learnslash=false;
43 int32_t wallm_load_clk=0;
44 int32_t sle_x,sle_y,sle_cnt,sle_clk=0;
45 int32_t vhead=0;
46 int32_t guycarryingitem=0;
47
48 char *guy_string[eMAXGUYS];
49
50 void never_return(int32_t index);
51 void playLevelMusic();
52
53 // If an enemy is this far out of the playing field, just remove it.
54 #define OUTOFBOUNDS ((int32_t)y>((isSideViewGravity() && canfall(id))?192:352) || y<-176 || x<-256 || x > 512)
55 //#define NEWOUTOFBOUNDS ((int32_t)y>32767 || y<-32767 || x<-32767 || x > 32767)
56 #define IGNORE_SIDEVIEW_PLATFORMS (editorflags & ENEMY_FLAG14)
57 #define OFFGRID_ENEMY (editorflags & ENEMY_FLAG15)
58
59 2582 void do_fix(zfix& coord, int32_t val, bool nearest_half = false)
60 {
61 2582 int32_t c = coord.getInt();
62
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2582 times.
2582 if(nearest_half)
63 {
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2582 times.
2582 if (c < 0)
65 c -= val / 2;
66 2582 else c += (val/2);
67 2582 }
68 2582 c -= c % val;
69 2582 coord = c;
70 2582 }
71
72 bool NEWOUTOFBOUNDS(zfix x, zfix y, zfix z)
73 {
74 return
75 (
76 (((int32_t)y) > FFCore.enemy_removal_point[spriteremovalY2])
77 || (((int32_t)y) < FFCore.enemy_removal_point[spriteremovalY1])
78 || (((int32_t)x) < FFCore.enemy_removal_point[spriteremovalX1])
79 || (((int32_t)x) > FFCore.enemy_removal_point[spriteremovalX2])
80 || (((int32_t)z) < FFCore.enemy_removal_point[spriteremovalZ1])
81 || (((int32_t)z) > FFCore.enemy_removal_point[spriteremovalZ2])
82 );
83 }
84
85 namespace
86 {
87 int32_t trapConstantHorizontalID;
88 int32_t trapConstantVerticalID;
89 int32_t trapLOSHorizontalID;
90 int32_t trapLOSVerticalID;
91 int32_t trapLOS4WayID;
92
93 int32_t cornerTrapID;
94 int32_t centerTrapID;
95
96 int32_t rockID;
97 int32_t zoraID;
98 int32_t statueID;
99 }
100
101 9 void identifyCFEnemies()
102 {
103 9 trapConstantHorizontalID=-1;
104 9 trapConstantVerticalID=-1;
105 9 trapLOSHorizontalID=-1;
106 9 trapLOSVerticalID=-1;
107 9 trapLOS4WayID=-1;
108 9 cornerTrapID=-1;
109 9 centerTrapID=-1;
110 9 rockID=-1;
111 9 zoraID=-1;
112 9 statueID=-1;
113
114
2/2
✓ Branch 0 taken 4608 times.
✓ Branch 1 taken 9 times.
4617 for(int32_t i=0; i<eMAXGUYS; i++)
115 {
116
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4599 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
4608 if((guysbuf[i].flags2&cmbflag_trph) && trapLOSHorizontalID==-1)
117 9 trapLOSHorizontalID=i;
118
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4599 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
4608 if((guysbuf[i].flags2&cmbflag_trpv) && trapLOSVerticalID==-1)
119 9 trapLOSVerticalID=i;
120
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4599 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
4608 if((guysbuf[i].flags2&cmbflag_trp4) && trapLOS4WayID==-1)
121 9 trapLOS4WayID=i;
122
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4599 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
4608 if((guysbuf[i].flags2&cmbflag_trplr) && trapConstantHorizontalID==-1)
123 9 trapConstantHorizontalID=i;
124
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4599 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
4608 if((guysbuf[i].flags2&cmbflag_trpud) && trapConstantVerticalID==-1)
125 9 trapConstantVerticalID=i;
126
127
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4599 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
4608 if((guysbuf[i].flags2&eneflag_trap) && cornerTrapID==-1)
128 9 cornerTrapID=i;
129
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4599 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
4608 if((guysbuf[i].flags2&eneflag_trp2) && centerTrapID==-1)
130 9 centerTrapID=i;
131
132
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4599 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
4608 if((guysbuf[i].flags2&eneflag_rock) && rockID==-1)
133 9 rockID=i;
134
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4599 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
4608 if((guysbuf[i].flags2&eneflag_zora) && zoraID==-1)
135 9 zoraID=i;
136
137
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4599 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
4608 if((guysbuf[i].flags2 & eneflag_fire) && statueID==-1)
138 9 statueID=i;
139 4608 }
140 9 }
141
142 int32_t random_layer_enemy()
143 {
144 int32_t cnt=count_layer_enemies();
145
146 if(cnt==0)
147 {
148 return eNONE;
149 }
150
151 int32_t ret=zc_oldrand()%cnt;
152 cnt=0;
153
154 for(int32_t i=0; i<6; ++i)
155 {
156 if(tmpscr->layermap[i]!=0)
157 {
158 mapscr *layerscreen=&TheMaps[(tmpscr->layermap[i]-1)*MAPSCRS]+tmpscr->layerscreen[i];
159
160 for(int32_t j=0; j<10; ++j)
161 {
162 if(layerscreen->enemy[j]>0&&layerscreen->enemy[j]<MAXGUYS)
163 {
164 if(cnt==ret)
165 {
166 return layerscreen->enemy[j];
167 }
168
169 ++cnt;
170 }
171 }
172 }
173 }
174
175 return eNONE;
176 }
177
178 int32_t count_layer_enemies()
179 {
180 int32_t cnt=0;
181
182 for(int32_t i=0; i<6; ++i)
183 {
184 if(tmpscr->layermap[i]!=0)
185 {
186 mapscr *layerscreen=&TheMaps[(tmpscr->layermap[i]-1)*MAPSCRS]+tmpscr->layerscreen[i];
187
188 for(int32_t j=0; j<10; ++j)
189 {
190 if(layerscreen->enemy[j]!=0)
191 {
192 ++cnt;
193 }
194 }
195 }
196 }
197
198 return cnt;
199 }
200
201 1183 int32_t hero_on_wall()
202 {
203 1183 zfix lx = Hero.getX();
204 1183 zfix ly = Hero.getY();
205
206
207 //zprint2("hero_on_wall x is: %d\n", lx);
208 //zprint2("hero_on_wall y is: %d\n", ly);
209
210
3/4
✓ Branch 0 taken 1182 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1182 times.
1183 if(lx>=48 && lx<=192)
211 {
212
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1179 times.
1182 if(ly==32) return up+1;
213
214
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1178 times.
1179 if(ly==128) return down+1;
215 1178 }
216
217
4/4
✓ Branch 0 taken 1102 times.
✓ Branch 1 taken 77 times.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 1025 times.
1179 if(ly>=48 && ly<=112)
218 {
219
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1024 times.
1025 if(lx==32) return left+1;
220
221
1/2
✓ Branch 0 taken 1024 times.
✗ Branch 1 not taken.
1024 if(lx==208) return right+1;
222 1024 }
223
224 1178 return 0;
225 1183 }
226
227 1717 bool tooclose(int32_t x,int32_t y,int32_t d)
228 {
229
2/2
✓ Branch 0 taken 1186 times.
✓ Branch 1 taken 531 times.
1717 return (abs(int32_t(HeroX())-x)<d && abs(int32_t(HeroY())-y)<d);
230 }
231
232 1846 bool enemy::overpit(enemy *e)
233 {
234
2/2
✓ Branch 0 taken 1846 times.
✓ Branch 1 taken 22152 times.
23998 for ( int32_t q = 0; q < hxsz; ++q )
235 {
236
2/2
✓ Branch 0 taken 177216 times.
✓ Branch 1 taken 22152 times.
199368 for ( int32_t q = 0; q < hysz; ++q )
237 {
238 //check every pixel of the hitbox
239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 177216 times.
177216 if ( ispitfall(x+q+hxofs, y+q+hyofs) )
240 {
241 //if the hitbox is over a pit, we can't land
242 return true;
243 }
244 177216 }
245 22152 }
246 1846 return false;
247 1846 }
248
249 23619 bool enemy::shadow_overpit(enemy *e)
250 {
251
2/2
✓ Branch 0 taken 23619 times.
✓ Branch 1 taken 377904 times.
401523 for ( int32_t q = 0; q < hxsz; ++q )
252 {
253
2/2
✓ Branch 0 taken 6046464 times.
✓ Branch 1 taken 377904 times.
6424368 for ( int32_t q = 0; q < hysz; ++q )
254 {
255 //check every pixel of the hitbox
256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6046464 times.
6046464 if ( ispitfall(x+q+hxofs, y+q+hyofs+hysz-2) )
257 {
258 //if the hitbox is over a pit, we can't land
259 return true;
260 }
261 6046464 }
262 377904 }
263 23619 return false;
264 23619 }
265
266 // Returns true iff a combo type or flag precludes enemy movement.
267 17880 bool enemy::groundblocked(int32_t dx, int32_t dy, bool isKB)
268 {
269
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17880 times.
17880 if(moveflags & FLAG_IGNORE_BLOCKFLAGS) return false;
270 17880 int32_t c = COMBOTYPE(dx,dy);
271
3/4
✓ Branch 0 taken 9878 times.
✓ Branch 1 taken 8002 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8002 times.
25882 bool pit_blocks = (!(moveflags & (FLAG_CAN_PITWALK|FLAG_ONLY_PITWALK)) && (!(moveflags & FLAG_CAN_PITFALL) || !isKB));
272
3/6
✓ Branch 0 taken 8002 times.
✓ Branch 1 taken 9878 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8002 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
17880 bool water_blocks = (!(moveflags & (FLAG_CAN_WATERWALK|FLAG_ONLY_WATERWALK|FLAG_ONLY_SHALLOW_WATERWALK)) && (!(moveflags & FLAG_CAN_WATERDROWN) || !isKB) && get_bit(quest_rules,qr_DROWN));
273
4/6
✓ Branch 0 taken 8036 times.
✓ Branch 1 taken 9844 times.
✓ Branch 2 taken 8036 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8036 times.
✗ Branch 5 not taken.
35760 return c==cPIT || c==cPITB || c==cPITC ||
274
4/6
✓ Branch 0 taken 8036 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8036 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4922 times.
✓ Branch 5 taken 3114 times.
8036 c==cPITD || c==cPITR || (pit_blocks && ispitfall(dx,dy)) ||
275 // Block enemies type and block enemies flags
276
2/2
✓ Branch 0 taken 8036 times.
✓ Branch 1 taken 4922 times.
3114 combo_class_buf[c].block_enemies&1 ||
277
2/4
✓ Branch 0 taken 8036 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8036 times.
✗ Branch 3 not taken.
8036 MAPFLAG(dx,dy)==mfNOENEMY || MAPCOMBOFLAG(dx,dy)==mfNOENEMY ||
278
2/4
✓ Branch 0 taken 8036 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8036 times.
✗ Branch 3 not taken.
8036 MAPFLAG(dx,dy)==mfNOGROUNDENEMY || MAPCOMBOFLAG(dx,dy)==mfNOGROUNDENEMY ||
279 // Check for ladder-only combos which aren't dried water
280
3/4
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 7960 times.
✓ Branch 2 taken 76 times.
✗ Branch 3 not taken.
16072 (combo_class_buf[c].ladder_pass&1 && !iswater_type(c)) ||
281 // Check for drownable water
282
4/4
✓ Branch 0 taken 6622 times.
✓ Branch 1 taken 1414 times.
✓ Branch 2 taken 3055 times.
✓ Branch 3 taken 3567 times.
8036 (water_blocks && !(isSideViewGravity()) && (iswaterex(MAPCOMBO(dx,dy), currmap, currscr, -1, dx, dy, false, false, true, false, false)));
283 8036 }
284
285 // Returns true iff enemy is floating and blocked by a combo type or flag.
286 4518 bool enemy::flyerblocked(int32_t dx, int32_t dy, int32_t special, bool isKB)
287 {
288
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4518 times.
4518 if(moveflags & FLAG_IGNORE_BLOCKFLAGS) return false;
289
3/4
✓ Branch 0 taken 2892 times.
✓ Branch 1 taken 1626 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1626 times.
6144 bool pit_blocks = (!(moveflags & FLAG_CAN_PITWALK) && (!(moveflags & FLAG_CAN_PITFALL) || !isKB));
290
3/4
✓ Branch 0 taken 2892 times.
✓ Branch 1 taken 1626 times.
✓ Branch 2 taken 1626 times.
✗ Branch 3 not taken.
6144 bool water_blocks = (!(moveflags & FLAG_CAN_WATERWALK) && (!(moveflags & FLAG_CAN_WATERDROWN) || !isKB));
291
2/2
✓ Branch 0 taken 1643 times.
✓ Branch 1 taken 2875 times.
7393 return ((special==spw_floater)&&
292
1/2
✓ Branch 0 taken 2875 times.
✗ Branch 1 not taken.
2875 ((COMBOTYPE(dx,dy)==cNOFLYZONE)||
293
1/2
✓ Branch 0 taken 2875 times.
✗ Branch 1 not taken.
2875 (combo_class_buf[COMBOTYPE(dx,dy)].block_enemies&4)||
294
1/2
✓ Branch 0 taken 2875 times.
✗ Branch 1 not taken.
2875 (MAPFLAG(dx,dy)==mfNOENEMY)||
295
1/2
✓ Branch 0 taken 2875 times.
✗ Branch 1 not taken.
2875 (MAPCOMBOFLAG(dx,dy)==mfNOENEMY)||
296
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2875 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5750 (water_blocks && iswaterex(MAPCOMBO(dx, dy), currmap, currscr, -1, dx,dy, false, false, true)) ||
297
1/2
✓ Branch 0 taken 2875 times.
✗ Branch 1 not taken.
2875 (pit_blocks && ispitfall(dx,dy))));
298 4518 }
299 // Returns true iff a combo type or flag precludes enemy movement.
300 1197 bool groundblocked(int32_t dx, int32_t dy, guydata const& gd)
301 {
302 1197 int32_t c = COMBOTYPE(dx,dy);
303 1197 bool pit_blocks = !(gd.moveflags & FLAG_CAN_PITWALK);
304
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1188 times.
1197 bool water_blocks = !(gd.moveflags & FLAG_CAN_WATERWALK) && get_bit(quest_rules,qr_DROWN);
305
3/6
✓ Branch 0 taken 1197 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1197 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1197 times.
✗ Branch 5 not taken.
4770 return c==cPIT || c==cPITB || c==cPITC ||
306
4/6
✓ Branch 0 taken 1197 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1197 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1188 times.
✓ Branch 5 taken 9 times.
1197 c==cPITD || c==cPITR || (pit_blocks && ispitfall(dx,dy)) ||
307 // Block enemies type and block enemies flags
308
2/2
✓ Branch 0 taken 1197 times.
✓ Branch 1 taken 1188 times.
9 combo_class_buf[c].block_enemies&1 ||
309
2/4
✓ Branch 0 taken 1197 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1197 times.
✗ Branch 3 not taken.
1197 MAPFLAG(dx,dy)==mfNOENEMY || MAPCOMBOFLAG(dx,dy)==mfNOENEMY ||
310
2/4
✓ Branch 0 taken 1197 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1197 times.
✗ Branch 3 not taken.
1197 MAPFLAG(dx,dy)==mfNOGROUNDENEMY || MAPCOMBOFLAG(dx,dy)==mfNOGROUNDENEMY ||
311 // Check for ladder-only combos which aren't dried water
312
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1193 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
2394 (combo_class_buf[c].ladder_pass&1 && !iswater_type(c)) ||
313 // Check for drownable water
314
4/4
✓ Branch 0 taken 1140 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 1107 times.
✓ Branch 3 taken 33 times.
1197 (water_blocks && !(isSideViewGravity()) && (iswaterex(MAPCOMBO(dx,dy), currmap, currscr, -1, dx, dy, false, false, true)));
315 }
316
317 // Returns true iff enemy is floating and blocked by a combo type or flag.
318 19 bool flyerblocked(int32_t dx, int32_t dy, int32_t special, guydata const& gd)
319 {
320
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 bool pit_blocks = (!(gd.moveflags & FLAG_CAN_PITWALK) && !(gd.moveflags & FLAG_CAN_PITFALL));
321 19 bool water_blocks = !(gd.moveflags & FLAG_CAN_WATERWALK);
322
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
38 return ((special==spw_floater)&&
323
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 ((COMBOTYPE(dx,dy)==cNOFLYZONE)||
324
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 (combo_class_buf[COMBOTYPE(dx,dy)].block_enemies&4)||
325
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 (MAPFLAG(dx,dy)==mfNOENEMY)||
326
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 (MAPCOMBOFLAG(dx,dy)==mfNOENEMY)||
327
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
38 (water_blocks && iswaterex(MAPCOMBO(dx,dy), currmap, currscr, -1, dx, dy, false, false, true)) ||
328
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 (pit_blocks && ispitfall(dx,dy))));
329 }
330
331 /**********************************/
332 /******* Enemy Base Class *******/
333 /**********************************/
334
335 /* ROM data flags
336
337 */
338
339 eFire::eFire(eFire const & other, bool new_script_uid, bool clear_parent_script_UID):
340 //Struct Element Type Purpose
341 //sprite(other),
342 enemy(other),
343 clk4(other.clk4),
344 shield(other.shield)
345
346 {
347
348 //arrays
349
350 if(other.scrmem)
351 {
352 alloc_scriptmem();
353 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
354
355 scrmem->scriptData = other.scrmem->scriptData;
356 }
357 else scrmem = NULL;
358 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
359 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
360
361 for(int32_t i=0; i<edefLAST255; i++)
362 defense[i]=other.defense[i];
363 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
364 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
365
366 if(new_script_uid)
367 {
368 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
369 }
370 if(clear_parent_script_UID)
371 {
372 parent_script_UID = 0;
373 }
374 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
375 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
376
377 for ( int32_t q = 0; q < 8; q++ )
378 {
379 initD[q] = other.initD[q];
380 weap_initiald[q] = other.weap_initiald[q];
381 }
382 for ( int32_t q = 0; q < 2; q++ )
383 {
384 initA[q] = other.initA[q];
385 weap_initiala[q] = other.weap_initiala[q];
386 }
387 }
388
389 eOther::eOther(eOther const & other, bool new_script_uid, bool clear_parent_script_UID):
390 //Struct Element Type Purpose
391 //sprite(other),
392 enemy(other),
393 clk4(other.clk4),
394 shield(other.shield)
395
396 {
397
398 //arrays
399
400 if(other.scrmem)
401 {
402 alloc_scriptmem();
403 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
404
405 scrmem->scriptData = other.scrmem->scriptData;
406 }
407 else scrmem = NULL;
408 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
409 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
410
411 for(int32_t i=0; i<edefLAST255; i++)
412 defense[i]=other.defense[i];
413 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
414 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
415
416 if(new_script_uid)
417 {
418 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
419 }
420 if(clear_parent_script_UID)
421 {
422 parent_script_UID = 0;
423 }
424 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
425 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
426
427 for ( int32_t q = 0; q < 8; q++ )
428 {
429 initD[q] = other.initD[q];
430 weap_initiald[q] = other.weap_initiald[q];
431 }
432 for ( int32_t q = 0; q < 2; q++ )
433 {
434 initA[q] = other.initA[q];
435 weap_initiala[q] = other.weap_initiala[q];
436 }
437 }
438
439
440
441
442 eScript::eScript(eScript const & other, bool new_script_uid, bool clear_parent_script_UID):
443 //Struct Element Type Purpose
444 //sprite(other),
445 enemy(other),
446 clk4(other.clk4),
447 shield(other.shield)
448
449 {
450
451 //arrays
452
453 if(other.scrmem)
454 {
455 alloc_scriptmem();
456 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
457
458 scrmem->scriptData = other.scrmem->scriptData;
459 }
460 else scrmem = NULL;
461 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
462 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
463
464 for(int32_t i=0; i<edefLAST255; i++)
465 defense[i]=other.defense[i];
466 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
467 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
468
469 if(new_script_uid)
470 {
471 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
472 }
473 if(clear_parent_script_UID)
474 {
475 parent_script_UID = 0;
476 }
477 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
478 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
479
480 for ( int32_t q = 0; q < 8; q++ )
481 {
482 initD[q] = other.initD[q];
483 weap_initiald[q] = other.weap_initiald[q];
484 }
485 for ( int32_t q = 0; q < 2; q++ )
486 {
487 initA[q] = other.initA[q];
488 weap_initiala[q] = other.weap_initiala[q];
489 }
490 }
491
492 eFriendly::eFriendly(eFriendly const & other, bool new_script_uid, bool clear_parent_script_UID):
493 //Struct Element Type Purpose
494 //sprite(other),
495 enemy(other),
496 clk4(other.clk4),
497 shield(other.shield)
498
499 {
500
501 //arrays
502
503 if(other.scrmem)
504 {
505 alloc_scriptmem();
506 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
507
508 scrmem->scriptData = other.scrmem->scriptData;
509 }
510 else scrmem = NULL;
511 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
512 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
513
514 for(int32_t i=0; i<edefLAST255; i++)
515 defense[i]=other.defense[i];
516 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
517 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
518
519 if(new_script_uid)
520 {
521 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
522 }
523 if(clear_parent_script_UID)
524 {
525 parent_script_UID = 0;
526 }
527 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
528 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
529
530 for ( int32_t q = 0; q < 8; q++ )
531 {
532 initD[q] = other.initD[q];
533 weap_initiald[q] = other.weap_initiald[q];
534 }
535 for ( int32_t q = 0; q < 2; q++ )
536 {
537 initA[q] = other.initA[q];
538 weap_initiala[q] = other.weap_initiala[q];
539 }
540 }
541
542 eGhini::eGhini(eGhini const & other, bool new_script_uid, bool clear_parent_script_UID):
543 //Struct Element Type Purpose
544 //sprite(other),
545 enemy(other),
546 clk4(other.clk4),
547 ox(other.ox),
548 oy(other.oy),
549 c(other.c)
550
551 {
552
553 //arrays
554
555 if(other.scrmem)
556 {
557 alloc_scriptmem();
558 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
559
560 scrmem->scriptData = other.scrmem->scriptData;
561 }
562 else scrmem = NULL;
563 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
564 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
565
566 for(int32_t i=0; i<edefLAST255; i++)
567 defense[i]=other.defense[i];
568 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
569 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
570
571 if(new_script_uid)
572 {
573 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
574 }
575 if(clear_parent_script_UID)
576 {
577 parent_script_UID = 0;
578 }
579 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
580 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
581
582 for ( int32_t q = 0; q < 8; q++ )
583 {
584 initD[q] = other.initD[q];
585 weap_initiald[q] = other.weap_initiald[q];
586 }
587 for ( int32_t q = 0; q < 2; q++ )
588 {
589 initA[q] = other.initA[q];
590 weap_initiala[q] = other.weap_initiala[q];
591 }
592 }
593
594 eTektite::eTektite(eTektite const & other, bool new_script_uid, bool clear_parent_script_UID):
595 //Struct Element Type Purpose
596 //sprite(other),
597 enemy(other),
598 old_y(other.old_y),
599 clk2start(other.clk2start),
600 cstart(other.cstart),
601 c(other.c)
602
603 {
604
605 //arrays
606
607 if(other.scrmem)
608 {
609 alloc_scriptmem();
610 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
611
612 scrmem->scriptData = other.scrmem->scriptData;
613 }
614 else scrmem = NULL;
615 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
616 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
617
618 for(int32_t i=0; i<edefLAST255; i++)
619 defense[i]=other.defense[i];
620 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
621 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
622
623 if(new_script_uid)
624 {
625 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
626 }
627 if(clear_parent_script_UID)
628 {
629 parent_script_UID = 0;
630 }
631 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
632 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
633
634 for ( int32_t q = 0; q < 8; q++ )
635 {
636 initD[q] = other.initD[q];
637 weap_initiald[q] = other.weap_initiald[q];
638 }
639 for ( int32_t q = 0; q < 2; q++ )
640 {
641 initA[q] = other.initA[q];
642 weap_initiala[q] = other.weap_initiala[q];
643 }
644 }
645
646 eItemFairy::eItemFairy(eItemFairy const & other, bool new_script_uid, bool clear_parent_script_UID):
647 //Struct Element Type Purpose
648 //sprite(other),
649 enemy(other)
650 {
651
652 //arrays
653
654 if(other.scrmem)
655 {
656 alloc_scriptmem();
657 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
658
659 scrmem->scriptData = other.scrmem->scriptData;
660 }
661 else scrmem = NULL;
662 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
663 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
664
665 for(int32_t i=0; i<edefLAST255; i++)
666 defense[i]=other.defense[i];
667 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
668 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
669
670 if(new_script_uid)
671 {
672 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
673 }
674 if(clear_parent_script_UID)
675 {
676 parent_script_UID = 0;
677 }
678 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
679 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
680
681 for ( int32_t q = 0; q < 8; q++ )
682 {
683 initD[q] = other.initD[q];
684 weap_initiald[q] = other.weap_initiald[q];
685 }
686 for ( int32_t q = 0; q < 2; q++ )
687 {
688 initA[q] = other.initA[q];
689 weap_initiala[q] = other.weap_initiala[q];
690 }
691 }
692
693 ePeahat::ePeahat(ePeahat const & other, bool new_script_uid, bool clear_parent_script_UID):
694 //Struct Element Type Purpose
695 //sprite(other),
696 enemy(other),
697 ox(other.ox),
698 oy(other.oy),
699 c(other.c)
700 {
701
702 //arrays
703
704 if(other.scrmem)
705 {
706 alloc_scriptmem();
707 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
708
709 scrmem->scriptData = other.scrmem->scriptData;
710 }
711 else scrmem = NULL;
712 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
713 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
714
715 for(int32_t i=0; i<edefLAST255; i++)
716 defense[i]=other.defense[i];
717 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
718 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
719
720 if(new_script_uid)
721 {
722 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
723 }
724 if(clear_parent_script_UID)
725 {
726 parent_script_UID = 0;
727 }
728 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
729 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
730
731 for ( int32_t q = 0; q < 8; q++ )
732 {
733 initD[q] = other.initD[q];
734 weap_initiald[q] = other.weap_initiald[q];
735 }
736 for ( int32_t q = 0; q < 2; q++ )
737 {
738 initA[q] = other.initA[q];
739 weap_initiala[q] = other.weap_initiala[q];
740 }
741 }
742
743 eLeever::eLeever(eLeever const & other, bool new_script_uid, bool clear_parent_script_UID):
744 //Struct Element Type Purpose
745 //sprite(other),
746 enemy(other),
747 temprule(other.temprule)
748 {
749
750 //arrays
751
752 if(other.scrmem)
753 {
754 alloc_scriptmem();
755 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
756
757 scrmem->scriptData = other.scrmem->scriptData;
758 }
759 else scrmem = NULL;
760 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
761 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
762
763 for(int32_t i=0; i<edefLAST255; i++)
764 defense[i]=other.defense[i];
765 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
766 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
767
768 if(new_script_uid)
769 {
770 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
771 }
772 if(clear_parent_script_UID)
773 {
774 parent_script_UID = 0;
775 }
776 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
777 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
778
779 for ( int32_t q = 0; q < 8; q++ )
780 {
781 initD[q] = other.initD[q];
782 weap_initiald[q] = other.weap_initiald[q];
783 }
784 for ( int32_t q = 0; q < 2; q++ )
785 {
786 initA[q] = other.initA[q];
787 weap_initiala[q] = other.weap_initiala[q];
788 }
789 }
790
791 eWallM::eWallM(eWallM const & other, bool new_script_uid, bool clear_parent_script_UID):
792 //Struct Element Type Purpose
793 //sprite(other),
794 enemy(other)
795 {
796
797 //arrays
798
799 if(other.scrmem)
800 {
801 alloc_scriptmem();
802 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
803
804 scrmem->scriptData = other.scrmem->scriptData;
805 }
806 else scrmem = NULL;
807 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
808 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
809
810 for(int32_t i=0; i<edefLAST255; i++)
811 defense[i]=other.defense[i];
812 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
813 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
814
815 if(new_script_uid)
816 {
817 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
818 }
819 if(clear_parent_script_UID)
820 {
821 parent_script_UID = 0;
822 }
823 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
824 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
825
826 for ( int32_t q = 0; q < 8; q++ )
827 {
828 initD[q] = other.initD[q];
829 weap_initiald[q] = other.weap_initiald[q];
830 }
831 for ( int32_t q = 0; q < 2; q++ )
832 {
833 initA[q] = other.initA[q];
834 weap_initiala[q] = other.weap_initiala[q];
835 }
836 }
837
838 eStalfos::eStalfos(eStalfos const & other, bool new_script_uid, bool clear_parent_script_UID):
839 //Struct Element Type Purpose
840 //sprite(other),
841 enemy(other),
842 clk4(other.clk4),
843 clk5(other.clk5),
844 fired(other.fired),
845 shield(other.shield),
846 dashing(other.dashing),
847 multishot(other.multishot),
848 fy(other.fy),
849 shadowdistance(other.shadowdistance)
850 {
851
852 //arrays
853
854 if(other.scrmem)
855 {
856 alloc_scriptmem();
857 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
858
859 scrmem->scriptData = other.scrmem->scriptData;
860 }
861 else scrmem = NULL;
862 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
863 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
864
865 for(int32_t i=0; i<edefLAST255; i++)
866 defense[i]=other.defense[i];
867 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
868 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
869
870 if(new_script_uid)
871 {
872 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
873 }
874 if(clear_parent_script_UID)
875 {
876 parent_script_UID = 0;
877 }
878 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
879 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
880
881 for ( int32_t q = 0; q < 8; q++ )
882 {
883 initD[q] = other.initD[q];
884 weap_initiald[q] = other.weap_initiald[q];
885 }
886 for ( int32_t q = 0; q < 2; q++ )
887 {
888 initA[q] = other.initA[q];
889 weap_initiala[q] = other.weap_initiala[q];
890 }
891 }
892
893 eZora::eZora(eZora const & other, bool new_script_uid, bool clear_parent_script_UID):
894 //Struct Element Type Purpose
895 //sprite(other),
896 enemy(other)
897 {
898
899 //arrays
900
901 if(other.scrmem)
902 {
903 alloc_scriptmem();
904 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
905
906 scrmem->scriptData = other.scrmem->scriptData;
907 }
908 else scrmem = NULL;
909 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
910 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
911
912 for(int32_t i=0; i<edefLAST255; i++)
913 defense[i]=other.defense[i];
914 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
915 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
916
917 if(new_script_uid)
918 {
919 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
920 }
921 if(clear_parent_script_UID)
922 {
923 parent_script_UID = 0;
924 }
925 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
926 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
927
928 for ( int32_t q = 0; q < 8; q++ )
929 {
930 initD[q] = other.initD[q];
931 weap_initiald[q] = other.weap_initiald[q];
932 }
933 for ( int32_t q = 0; q < 2; q++ )
934 {
935 initA[q] = other.initA[q];
936 weap_initiala[q] = other.weap_initiala[q];
937 }
938 }
939
940 eSpinTile::eSpinTile(eSpinTile const & other, bool new_script_uid, bool clear_parent_script_UID):
941 //Struct Element Type Purpose
942 //sprite(other),
943 enemy(other)
944 {
945
946 //arrays
947
948 if(other.scrmem)
949 {
950 alloc_scriptmem();
951 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
952
953 scrmem->scriptData = other.scrmem->scriptData;
954 }
955 else scrmem = NULL;
956 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
957 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
958
959 for(int32_t i=0; i<edefLAST255; i++)
960 defense[i]=other.defense[i];
961 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
962 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
963
964 if(new_script_uid)
965 {
966 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
967 }
968 if(clear_parent_script_UID)
969 {
970 parent_script_UID = 0;
971 }
972 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
973 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
974
975 for ( int32_t q = 0; q < 8; q++ )
976 {
977 initD[q] = other.initD[q];
978 weap_initiald[q] = other.weap_initiald[q];
979 }
980 for ( int32_t q = 0; q < 2; q++ )
981 {
982 initA[q] = other.initA[q];
983 weap_initiala[q] = other.weap_initiala[q];
984 }
985 }
986
987 eNPC::eNPC(eNPC const & other, bool new_script_uid, bool clear_parent_script_UID):
988 //Struct Element Type Purpose
989 //sprite(other),
990 enemy(other)
991 {
992
993 //arrays
994
995 if(other.scrmem)
996 {
997 alloc_scriptmem();
998 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
999
1000 scrmem->scriptData = other.scrmem->scriptData;
1001 }
1002 else scrmem = NULL;
1003 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1004 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1005
1006 for(int32_t i=0; i<edefLAST255; i++)
1007 defense[i]=other.defense[i];
1008 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1009 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1010
1011 if(new_script_uid)
1012 {
1013 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1014 }
1015 if(clear_parent_script_UID)
1016 {
1017 parent_script_UID = 0;
1018 }
1019 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1020 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1021
1022 for ( int32_t q = 0; q < 8; q++ )
1023 {
1024 initD[q] = other.initD[q];
1025 weap_initiald[q] = other.weap_initiald[q];
1026 }
1027 for ( int32_t q = 0; q < 2; q++ )
1028 {
1029 initA[q] = other.initA[q];
1030 weap_initiala[q] = other.weap_initiala[q];
1031 }
1032 }
1033
1034 eTrigger::eTrigger(eTrigger const & other, bool new_script_uid, bool clear_parent_script_UID):
1035 //Struct Element Type Purpose
1036 //sprite(other),
1037 enemy(other)
1038 {
1039
1040 //arrays
1041
1042 if(other.scrmem)
1043 {
1044 alloc_scriptmem();
1045 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1046
1047 scrmem->scriptData = other.scrmem->scriptData;
1048 }
1049 else scrmem = NULL;
1050 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1051 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1052
1053 for(int32_t i=0; i<edefLAST255; i++)
1054 defense[i]=other.defense[i];
1055 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1056 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1057
1058 if(new_script_uid)
1059 {
1060 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1061 }
1062 if(clear_parent_script_UID)
1063 {
1064 parent_script_UID = 0;
1065 }
1066 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1067 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1068
1069 for ( int32_t q = 0; q < 8; q++ )
1070 {
1071 initD[q] = other.initD[q];
1072 weap_initiald[q] = other.weap_initiald[q];
1073 }
1074 for ( int32_t q = 0; q < 2; q++ )
1075 {
1076 initA[q] = other.initA[q];
1077 weap_initiala[q] = other.weap_initiala[q];
1078 }
1079 }
1080
1081 eProjectile::eProjectile(eProjectile const & other, bool new_script_uid, bool clear_parent_script_UID):
1082 //Struct Element Type Purpose
1083 //sprite(other),
1084 enemy(other),
1085 minRange(other.minRange)
1086 {
1087
1088 //arrays
1089
1090 if(other.scrmem)
1091 {
1092 alloc_scriptmem();
1093 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1094
1095 scrmem->scriptData = other.scrmem->scriptData;
1096 }
1097 else scrmem = NULL;
1098 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1099 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1100
1101 for(int32_t i=0; i<edefLAST255; i++)
1102 defense[i]=other.defense[i];
1103 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1104 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1105
1106 if(new_script_uid)
1107 {
1108 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1109 }
1110 if(clear_parent_script_UID)
1111 {
1112 parent_script_UID = 0;
1113 }
1114 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1115 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1116
1117 for ( int32_t q = 0; q < 8; q++ )
1118 {
1119 initD[q] = other.initD[q];
1120 weap_initiald[q] = other.weap_initiald[q];
1121 }
1122 for ( int32_t q = 0; q < 2; q++ )
1123 {
1124 initA[q] = other.initA[q];
1125 weap_initiala[q] = other.weap_initiala[q];
1126 }
1127 }
1128
1129 eBoulder::eBoulder(eBoulder const & other, bool new_script_uid, bool clear_parent_script_UID):
1130 //Struct Element Type Purpose
1131 //sprite(other),
1132 enemy(other)
1133 {
1134
1135 //arrays
1136
1137 if(other.scrmem)
1138 {
1139 alloc_scriptmem();
1140 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1141
1142 scrmem->scriptData = other.scrmem->scriptData;
1143 }
1144 else scrmem = NULL;
1145 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1146 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1147
1148 for(int32_t i=0; i<edefLAST255; i++)
1149 defense[i]=other.defense[i];
1150 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1151 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1152
1153 if(new_script_uid)
1154 {
1155 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1156 }
1157 if(clear_parent_script_UID)
1158 {
1159 parent_script_UID = 0;
1160 }
1161 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1162 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1163
1164 for ( int32_t q = 0; q < 8; q++ )
1165 {
1166 initD[q] = other.initD[q];
1167 weap_initiald[q] = other.weap_initiald[q];
1168 }
1169 for ( int32_t q = 0; q < 2; q++ )
1170 {
1171 initA[q] = other.initA[q];
1172 weap_initiala[q] = other.weap_initiala[q];
1173 }
1174 }
1175
1176 eRock::eRock(eRock const & other, bool new_script_uid, bool clear_parent_script_UID):
1177 //Struct Element Type Purpose
1178 //sprite(other),
1179 enemy(other)
1180 {
1181
1182 //arrays
1183
1184 if(other.scrmem)
1185 {
1186 alloc_scriptmem();
1187 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1188
1189 scrmem->scriptData = other.scrmem->scriptData;
1190 }
1191 else scrmem = NULL;
1192 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1193 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1194
1195 for(int32_t i=0; i<edefLAST255; i++)
1196 defense[i]=other.defense[i];
1197 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1198 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1199
1200 if(new_script_uid)
1201 {
1202 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1203 }
1204 if(clear_parent_script_UID)
1205 {
1206 parent_script_UID = 0;
1207 }
1208 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1209 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1210
1211 for ( int32_t q = 0; q < 8; q++ )
1212 {
1213 initD[q] = other.initD[q];
1214 weap_initiald[q] = other.weap_initiald[q];
1215 }
1216 for ( int32_t q = 0; q < 2; q++ )
1217 {
1218 initA[q] = other.initA[q];
1219 weap_initiala[q] = other.weap_initiala[q];
1220 }
1221 }
1222
1223 eTrap2::eTrap2(eTrap2 const & other, bool new_script_uid, bool clear_parent_script_UID):
1224 //Struct Element Type Purpose
1225 //sprite(other),
1226 enemy(other)
1227 {
1228
1229 //arrays
1230
1231 if(other.scrmem)
1232 {
1233 alloc_scriptmem();
1234 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1235
1236 scrmem->scriptData = other.scrmem->scriptData;
1237 }
1238 else scrmem = NULL;
1239 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1240 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1241
1242 for(int32_t i=0; i<edefLAST255; i++)
1243 defense[i]=other.defense[i];
1244 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1245 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1246
1247 if(new_script_uid)
1248 {
1249 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1250 }
1251 if(clear_parent_script_UID)
1252 {
1253 parent_script_UID = 0;
1254 }
1255 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1256 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1257
1258 for ( int32_t q = 0; q < 8; q++ )
1259 {
1260 initD[q] = other.initD[q];
1261 weap_initiald[q] = other.weap_initiald[q];
1262 }
1263 for ( int32_t q = 0; q < 2; q++ )
1264 {
1265 initA[q] = other.initA[q];
1266 weap_initiala[q] = other.weap_initiala[q];
1267 }
1268 }
1269
1270 eTrap::eTrap(eTrap const & other, bool new_script_uid, bool clear_parent_script_UID):
1271 //Struct Element Type Purpose
1272 //sprite(other),
1273 enemy(other),
1274 ox(other.ox),
1275 oy(other.oy)
1276 {
1277
1278 //arrays
1279
1280 if(other.scrmem)
1281 {
1282 alloc_scriptmem();
1283 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1284
1285 scrmem->scriptData = other.scrmem->scriptData;
1286 }
1287 else scrmem = NULL;
1288 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1289 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1290
1291 for(int32_t i=0; i<edefLAST255; i++)
1292 defense[i]=other.defense[i];
1293 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1294 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1295
1296 if(new_script_uid)
1297 {
1298 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1299 }
1300 if(clear_parent_script_UID)
1301 {
1302 parent_script_UID = 0;
1303 }
1304 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1305 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1306
1307 for ( int32_t q = 0; q < 8; q++ )
1308 {
1309 initD[q] = other.initD[q];
1310 weap_initiald[q] = other.weap_initiald[q];
1311 }
1312 for ( int32_t q = 0; q < 2; q++ )
1313 {
1314 initA[q] = other.initA[q];
1315 weap_initiala[q] = other.weap_initiala[q];
1316 }
1317 }
1318
1319
1320
1321
1322 eKeese::eKeese(eKeese const & other, bool new_script_uid, bool clear_parent_script_UID):
1323 //Struct Element Type Purpose
1324 //sprite(other),
1325 enemy(other),
1326 ox(other.ox),
1327 c(other.c),
1328 clk4(other.clk4),
1329 oy(other.oy)
1330 {
1331
1332 //arrays
1333
1334 if(other.scrmem)
1335 {
1336 alloc_scriptmem();
1337 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1338
1339 scrmem->scriptData = other.scrmem->scriptData;
1340 }
1341 else scrmem = NULL;
1342 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1343 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1344
1345 for(int32_t i=0; i<edefLAST255; i++)
1346 defense[i]=other.defense[i];
1347 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1348 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1349
1350 if(new_script_uid)
1351 {
1352 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1353 }
1354 if(clear_parent_script_UID)
1355 {
1356 parent_script_UID = 0;
1357 }
1358 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1359 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1360
1361 for ( int32_t q = 0; q < 8; q++ )
1362 {
1363 initD[q] = other.initD[q];
1364 weap_initiald[q] = other.weap_initiald[q];
1365 }
1366 for ( int32_t q = 0; q < 2; q++ )
1367 {
1368 initA[q] = other.initA[q];
1369 weap_initiala[q] = other.weap_initiala[q];
1370 }
1371 }
1372
1373 eWizzrobe::eWizzrobe(eWizzrobe const & other, bool new_script_uid, bool clear_parent_script_UID):
1374 //Struct Element Type Purpose
1375 //sprite(other),
1376 enemy(other),
1377 charging(other.charging),
1378 firing(other.firing),
1379 fclk(other.fclk)
1380 {
1381
1382 //arrays
1383
1384 if(other.scrmem)
1385 {
1386 alloc_scriptmem();
1387 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1388
1389 scrmem->scriptData = other.scrmem->scriptData;
1390 }
1391 else scrmem = NULL;
1392 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1393 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1394
1395 for(int32_t i=0; i<edefLAST255; i++)
1396 defense[i]=other.defense[i];
1397 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1398 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1399
1400 if(new_script_uid)
1401 {
1402 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1403 }
1404 if(clear_parent_script_UID)
1405 {
1406 parent_script_UID = 0;
1407 }
1408 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1409 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1410
1411 for ( int32_t q = 0; q < 8; q++ )
1412 {
1413 initD[q] = other.initD[q];
1414 weap_initiald[q] = other.weap_initiald[q];
1415 }
1416 for ( int32_t q = 0; q < 2; q++ )
1417 {
1418 initA[q] = other.initA[q];
1419 weap_initiala[q] = other.weap_initiala[q];
1420 }
1421 }
1422
1423 eDodongo::eDodongo(eDodongo const & other, bool new_script_uid, bool clear_parent_script_UID):
1424 //Struct Element Type Purpose
1425 //sprite(other),
1426 enemy(other)
1427 {
1428
1429 //arrays
1430
1431 if(other.scrmem)
1432 {
1433 alloc_scriptmem();
1434 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1435
1436 scrmem->scriptData = other.scrmem->scriptData;
1437 }
1438 else scrmem = NULL;
1439 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1440 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1441
1442 for(int32_t i=0; i<edefLAST255; i++)
1443 defense[i]=other.defense[i];
1444 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1445 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1446
1447 if(new_script_uid)
1448 {
1449 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1450 }
1451 if(clear_parent_script_UID)
1452 {
1453 parent_script_UID = 0;
1454 }
1455 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1456 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1457
1458 for ( int32_t q = 0; q < 8; q++ )
1459 {
1460 initD[q] = other.initD[q];
1461 weap_initiald[q] = other.weap_initiald[q];
1462 }
1463 for ( int32_t q = 0; q < 2; q++ )
1464 {
1465 initA[q] = other.initA[q];
1466 weap_initiala[q] = other.weap_initiala[q];
1467 }
1468 }
1469
1470 eDodongo2::eDodongo2(eDodongo2 const & other, bool new_script_uid, bool clear_parent_script_UID):
1471 //Struct Element Type Purpose
1472 //sprite(other),
1473 enemy(other),
1474 previous_dir(other.previous_dir)
1475 {
1476
1477 //arrays
1478
1479 if(other.scrmem)
1480 {
1481 alloc_scriptmem();
1482 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1483
1484 scrmem->scriptData = other.scrmem->scriptData;
1485 }
1486 else scrmem = NULL;
1487 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1488 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1489
1490 for(int32_t i=0; i<edefLAST255; i++)
1491 defense[i]=other.defense[i];
1492 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1493 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1494
1495 if(new_script_uid)
1496 {
1497 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1498 }
1499 if(clear_parent_script_UID)
1500 {
1501 parent_script_UID = 0;
1502 }
1503 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1504 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1505
1506 for ( int32_t q = 0; q < 8; q++ )
1507 {
1508 initD[q] = other.initD[q];
1509 weap_initiald[q] = other.weap_initiald[q];
1510 }
1511 for ( int32_t q = 0; q < 2; q++ )
1512 {
1513 initA[q] = other.initA[q];
1514 weap_initiala[q] = other.weap_initiala[q];
1515 }
1516 }
1517
1518 eAquamentus::eAquamentus(eAquamentus const & other, bool new_script_uid, bool clear_parent_script_UID):
1519 //Struct Element Type Purpose
1520 //sprite(other),
1521 enemy(other),
1522 fbx(other.fbx),
1523 clk4(other.clk4)
1524 {
1525
1526 //arrays
1527
1528 if(other.scrmem)
1529 {
1530 alloc_scriptmem();
1531 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1532
1533 scrmem->scriptData = other.scrmem->scriptData;
1534 }
1535 else scrmem = NULL;
1536 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1537 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1538
1539 for(int32_t i=0; i<edefLAST255; i++)
1540 defense[i]=other.defense[i];
1541 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1542 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1543
1544 if(new_script_uid)
1545 {
1546 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1547 }
1548 if(clear_parent_script_UID)
1549 {
1550 parent_script_UID = 0;
1551 }
1552 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1553 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1554
1555 for ( int32_t q = 0; q < 8; q++ )
1556 {
1557 initD[q] = other.initD[q];
1558 weap_initiald[q] = other.weap_initiald[q];
1559 }
1560 for ( int32_t q = 0; q < 2; q++ )
1561 {
1562 initA[q] = other.initA[q];
1563 weap_initiala[q] = other.weap_initiala[q];
1564 }
1565 }
1566
1567 eGohma::eGohma(eGohma const & other, bool new_script_uid, bool clear_parent_script_UID):
1568 //Struct Element Type Purpose
1569 //sprite(other),
1570 enemy(other),
1571 clk4(other.clk4)
1572 {
1573
1574 //arrays
1575
1576 if(other.scrmem)
1577 {
1578 alloc_scriptmem();
1579 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1580
1581 scrmem->scriptData = other.scrmem->scriptData;
1582 }
1583 else scrmem = NULL;
1584 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1585 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1586
1587 for(int32_t i=0; i<edefLAST255; i++)
1588 defense[i]=other.defense[i];
1589 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1590 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1591
1592 if(new_script_uid)
1593 {
1594 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1595 }
1596 if(clear_parent_script_UID)
1597 {
1598 parent_script_UID = 0;
1599 }
1600 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1601 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1602
1603 for ( int32_t q = 0; q < 8; q++ )
1604 {
1605 initD[q] = other.initD[q];
1606 weap_initiald[q] = other.weap_initiald[q];
1607 }
1608 for ( int32_t q = 0; q < 2; q++ )
1609 {
1610 initA[q] = other.initA[q];
1611 weap_initiala[q] = other.weap_initiala[q];
1612 }
1613 }
1614
1615 eLilDig::eLilDig(eLilDig const & other, bool new_script_uid, bool clear_parent_script_UID):
1616 //Struct Element Type Purpose
1617 //sprite(other),
1618 enemy(other)
1619 {
1620
1621 //arrays
1622
1623 if(other.scrmem)
1624 {
1625 alloc_scriptmem();
1626 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1627
1628 scrmem->scriptData = other.scrmem->scriptData;
1629 }
1630 else scrmem = NULL;
1631 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1632 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1633
1634 for(int32_t i=0; i<edefLAST255; i++)
1635 defense[i]=other.defense[i];
1636 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1637 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1638
1639 if(new_script_uid)
1640 {
1641 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1642 }
1643 if(clear_parent_script_UID)
1644 {
1645 parent_script_UID = 0;
1646 }
1647 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1648 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1649
1650 for ( int32_t q = 0; q < 8; q++ )
1651 {
1652 initD[q] = other.initD[q];
1653 weap_initiald[q] = other.weap_initiald[q];
1654 }
1655 for ( int32_t q = 0; q < 2; q++ )
1656 {
1657 initA[q] = other.initA[q];
1658 weap_initiala[q] = other.weap_initiala[q];
1659 }
1660 }
1661
1662 eBigDig::eBigDig(eBigDig const & other, bool new_script_uid, bool clear_parent_script_UID):
1663 //Struct Element Type Purpose
1664 //sprite(other),
1665 enemy(other)
1666 {
1667
1668 //arrays
1669
1670 if(other.scrmem)
1671 {
1672 alloc_scriptmem();
1673 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1674
1675 scrmem->scriptData = other.scrmem->scriptData;
1676 }
1677 else scrmem = NULL;
1678 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1679 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1680
1681 for(int32_t i=0; i<edefLAST255; i++)
1682 defense[i]=other.defense[i];
1683 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1684 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1685
1686 if(new_script_uid)
1687 {
1688 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1689 }
1690 if(clear_parent_script_UID)
1691 {
1692 parent_script_UID = 0;
1693 }
1694 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1695 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1696
1697 for ( int32_t q = 0; q < 8; q++ )
1698 {
1699 initD[q] = other.initD[q];
1700 weap_initiald[q] = other.weap_initiald[q];
1701 }
1702 for ( int32_t q = 0; q < 2; q++ )
1703 {
1704 initA[q] = other.initA[q];
1705 weap_initiala[q] = other.weap_initiala[q];
1706 }
1707 }
1708
1709 eGanon::eGanon(eGanon const & other, bool new_script_uid, bool clear_parent_script_UID):
1710 //Struct Element Type Purpose
1711 //sprite(other),
1712 enemy(other),
1713 Stunclk(other.Stunclk)
1714
1715 {
1716
1717 //arrays
1718
1719 if(other.scrmem)
1720 {
1721 alloc_scriptmem();
1722 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1723
1724 scrmem->scriptData = other.scrmem->scriptData;
1725 }
1726 else scrmem = NULL;
1727 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1728 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1729
1730 for(int32_t i=0; i<edefLAST255; i++)
1731 defense[i]=other.defense[i];
1732 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1733 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1734
1735 if(new_script_uid)
1736 {
1737 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1738 }
1739 if(clear_parent_script_UID)
1740 {
1741 parent_script_UID = 0;
1742 }
1743 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1744 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1745
1746 for ( int32_t q = 0; q < 8; q++ )
1747 {
1748 initD[q] = other.initD[q];
1749 weap_initiald[q] = other.weap_initiald[q];
1750 }
1751 for ( int32_t q = 0; q < 2; q++ )
1752 {
1753 initA[q] = other.initA[q];
1754 weap_initiala[q] = other.weap_initiala[q];
1755 }
1756 }
1757
1758 eMoldorm::eMoldorm(eMoldorm const & other, bool new_script_uid, bool clear_parent_script_UID):
1759 //Struct Element Type Purpose
1760 //sprite(other),
1761 enemy(other),
1762 segcnt(other.segcnt),
1763 segid(other.segid)
1764
1765 {
1766
1767 //arrays
1768
1769 if(other.scrmem)
1770 {
1771 alloc_scriptmem();
1772 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1773
1774 scrmem->scriptData = other.scrmem->scriptData;
1775 }
1776 else scrmem = NULL;
1777 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1778 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1779
1780 for(int32_t i=0; i<edefLAST255; i++)
1781 defense[i]=other.defense[i];
1782 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1783 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1784
1785 if(new_script_uid)
1786 {
1787 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1788 }
1789 if(clear_parent_script_UID)
1790 {
1791 parent_script_UID = 0;
1792 }
1793 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1794 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1795
1796 for ( int32_t q = 0; q < 8; q++ )
1797 {
1798 initD[q] = other.initD[q];
1799 weap_initiald[q] = other.weap_initiald[q];
1800 }
1801 for ( int32_t q = 0; q < 2; q++ )
1802 {
1803 initA[q] = other.initA[q];
1804 weap_initiala[q] = other.weap_initiala[q];
1805 }
1806 }
1807
1808 esMoldorm::esMoldorm(esMoldorm const & other, bool new_script_uid, bool clear_parent_script_UID):
1809 //Struct Element Type Purpose
1810 //sprite(other),
1811 enemy(other),
1812 parentclk(other.parentclk)
1813 {
1814
1815 //arrays
1816
1817 if(other.scrmem)
1818 {
1819 alloc_scriptmem();
1820 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1821
1822 scrmem->scriptData = other.scrmem->scriptData;
1823 }
1824 else scrmem = NULL;
1825 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1826 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1827
1828 for(int32_t i=0; i<edefLAST255; i++)
1829 defense[i]=other.defense[i];
1830 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1831 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1832
1833 if(new_script_uid)
1834 {
1835 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1836 }
1837 if(clear_parent_script_UID)
1838 {
1839 parent_script_UID = 0;
1840 }
1841 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1842 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1843
1844 for ( int32_t q = 0; q < 8; q++ )
1845 {
1846 initD[q] = other.initD[q];
1847 weap_initiald[q] = other.weap_initiald[q];
1848 }
1849 for ( int32_t q = 0; q < 2; q++ )
1850 {
1851 initA[q] = other.initA[q];
1852 weap_initiala[q] = other.weap_initiala[q];
1853 }
1854 }
1855 /*
1856 eManhandla::eManhandla(eManhandla const & other, bool new_script_uid, bool clear_parent_script_UID):
1857 //Struct Element Type Purpose
1858 //sprite(other),
1859 enemy(other),
1860 armcnt(armcnt),
1861 adjusted(adjusted),
1862 arm[0](arm[0]),
1863 arm[1](arm[1]),
1864 arm[2](arm[2]),
1865 arm[3](arm[3]),
1866 arm[4](arm[4]),
1867 arm[5](arm[5]),
1868 arm[6](arm[6]),
1869 arm[7](arm[7])
1870 {
1871
1872 //arrays
1873 if(other.scrmem)
1874 {
1875 alloc_scriptmem();
1876 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1877
1878 scrmem->scriptData = other.scrmem->scriptData;
1879 }
1880 else scrmem = NULL;
1881 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1882 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1883
1884 for(int32_t i=0; i<edefLAST255; i++)
1885 defense[i]=other.defense[i];
1886 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1887 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1888
1889 if(new_script_uid)
1890 {
1891 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1892 }
1893 if(clear_parent_script_UID)
1894 {
1895 parent_script_UID = 0;
1896 }
1897 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1898 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1899
1900 for ( int32_t q = 0; q < 8; q++ )
1901 {
1902 initD[q] = other.initD[q];
1903 weap_initiald[q] = other.weap_initiald[q];
1904 }
1905 for ( int32_t q = 0; q < 2; q++ )
1906 {
1907 initA[q] = other.initA[q];
1908 weap_initiala[q] = other.weap_initiala[q];
1909 }
1910 }
1911
1912 esManhandla::esManhandla(esManhandla const & other, bool new_script_uid, bool clear_parent_script_UID):
1913 //Struct Element Type Purpose
1914 //sprite(other),
1915 enemy(other)
1916 {
1917
1918 //arrays
1919 if(other.scrmem)
1920 {
1921 alloc_scriptmem();
1922 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1923
1924 scrmem->scriptData = other.scrmem->scriptData;
1925 }
1926 else scrmem = NULL;
1927 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1928 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1929
1930 for(int32_t i=0; i<edefLAST255; i++)
1931 defense[i]=other.defense[i];
1932 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1933 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1934
1935 if(new_script_uid)
1936 {
1937 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1938 }
1939 if(clear_parent_script_UID)
1940 {
1941 parent_script_UID = 0;
1942 }
1943 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1944 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1945
1946 for ( int32_t q = 0; q < 8; q++ )
1947 {
1948 initD[q] = other.initD[q];
1949 weap_initiald[q] = other.weap_initiald[q];
1950 }
1951 for ( int32_t q = 0; q < 2; q++ )
1952 {
1953 initA[q] = other.initA[q];
1954 weap_initiala[q] = other.weap_initiala[q];
1955 }
1956 }
1957
1958 eGleeok::eGleeok(eGleeok const & other, bool new_script_uid, bool clear_parent_script_UID):
1959 //Struct Element Type Purpose
1960 //sprite(other),
1961 enemy(other),
1962 flameclk(flameclk),
1963 flamehead(flamehead),
1964 necktile(necktile)
1965
1966 {
1967
1968 //arrays
1969
1970 if(other.scrmem)
1971 {
1972 alloc_scriptmem();
1973 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1974
1975 scrmem->scriptData = other.scrmem->scriptData;
1976 }
1977 else scrmem = NULL;
1978 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1979 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1980
1981 for(int32_t i=0; i<edefLAST255; i++)
1982 defense[i]=other.defense[i];
1983 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1984 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1985
1986 if(new_script_uid)
1987 {
1988 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1989 }
1990 if(clear_parent_script_UID)
1991 {
1992 parent_script_UID = 0;
1993 }
1994 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1995 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1996
1997 for ( int32_t q = 0; q < 8; q++ )
1998 {
1999 initD[q] = other.initD[q];
2000 weap_initiald[q] = other.weap_initiald[q];
2001 }
2002 for ( int32_t q = 0; q < 2; q++ )
2003 {
2004 initA[q] = other.initA[q];
2005 weap_initiala[q] = other.weap_initiala[q];
2006 }
2007 }
2008
2009 esGleeok::esGleeok(esGleeok const & other, bool new_script_uid, bool clear_parent_script_UID):
2010 //Struct Element Type Purpose
2011 //sprite(other),
2012 enemy(other),
2013 headtile(headtile),
2014 flyingheadtile(flyingheadtile),
2015 necktile(necktile),
2016 xoffset(xoffset),
2017 yoffset(yoffset),
2018 nx(nx),
2019 ny(ny),
2020 nxoffset(nxoffset),
2021 nyoffset(nyoffset),
2022 parent(parent)
2023
2024 {
2025
2026 //arrays
2027
2028 if(other.scrmem)
2029 {
2030 alloc_scriptmem();
2031 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2032
2033 scrmem->scriptData = other.scrmem->scriptData;
2034 }
2035 else scrmem = NULL;
2036 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2037 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2038
2039 //for ( int32_t q = 0; q < 255; q++ )
2040 //{
2041 // nx[q] = other.nx[q];
2042 // ny[q] = other.ny[q];
2043 // nxoffset[q] = other.nxoffset[q];
2044 // nyoffset[q] = other.nyoffset[q];
2045 //}
2046
2047 for(int32_t i=0; i<edefLAST255; i++)
2048 defense[i]=other.defense[i];
2049 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2050 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2051
2052 if(new_script_uid)
2053 {
2054 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2055 }
2056 if(clear_parent_script_UID)
2057 {
2058 parent_script_UID = 0;
2059 }
2060 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2061 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2062
2063 for ( int32_t q = 0; q < 8; q++ )
2064 {
2065 initD[q] = other.initD[q];
2066 weap_initiald[q] = other.weap_initiald[q];
2067 }
2068 for ( int32_t q = 0; q < 2; q++ )
2069 {
2070 initA[q] = other.initA[q];
2071 weap_initiala[q] = other.weap_initiala[q];
2072 }
2073 }
2074
2075 ePatra::ePatra(ePatra const & other, bool new_script_uid, bool clear_parent_script_UID):
2076 //Struct Element Type Purpose
2077 //sprite(other),
2078 enemy(other),
2079 flycnt(flycnt),
2080 flycnt2(flycnt2),
2081 loopcnt(loopcnt),
2082 lookat(lookat),
2083 circle_x(circle_x),
2084 circle_y(circle_y),
2085 temp_x(temp_x),
2086 temp_y(temp_y),
2087 adjusted(adjusted)
2088
2089 {
2090
2091 //arrays
2092
2093 if(other.scrmem)
2094 {
2095 alloc_scriptmem();
2096 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2097
2098 scrmem->scriptData = other.scrmem->scriptData;
2099 }
2100 else scrmem = NULL;
2101 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2102 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2103
2104 for(int32_t i=0; i<edefLAST255; i++)
2105 defense[i]=other.defense[i];
2106 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2107 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2108
2109 if(new_script_uid)
2110 {
2111 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2112 }
2113 if(clear_parent_script_UID)
2114 {
2115 parent_script_UID = 0;
2116 }
2117 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2118 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2119
2120 for ( int32_t q = 0; q < 8; q++ )
2121 {
2122 initD[q] = other.initD[q];
2123 weap_initiald[q] = other.weap_initiald[q];
2124 }
2125 for ( int32_t q = 0; q < 2; q++ )
2126 {
2127 initA[q] = other.initA[q];
2128 weap_initiala[q] = other.weap_initiala[q];
2129 }
2130 }
2131
2132 ePatraBS::ePatraBS(ePatraBS const & other, bool new_script_uid, bool clear_parent_script_UID):
2133 //Struct Element Type Purpose
2134 //sprite(other),
2135 enemy(other),
2136 flycnt(flycnt),
2137 flycnt2(flycnt2),
2138 loopcnt(loopcnt),
2139 lookat(lookat),
2140 adjusted(adjusted)
2141
2142 {
2143
2144 //arrays
2145
2146 if(other.scrmem)
2147 {
2148 alloc_scriptmem();
2149 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2150
2151 scrmem->scriptData = other.scrmem->scriptData;
2152 }
2153 else scrmem = NULL;
2154 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2155 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2156
2157 for(int32_t i=0; i<edefLAST255; i++)
2158 defense[i]=other.defense[i];
2159 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2160 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2161
2162 if(new_script_uid)
2163 {
2164 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2165 }
2166 if(clear_parent_script_UID)
2167 {
2168 parent_script_UID = 0;
2169 }
2170 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2171 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2172
2173 for ( int32_t q = 0; q < 8; q++ )
2174 {
2175 initD[q] = other.initD[q];
2176 weap_initiald[q] = other.weap_initiald[q];
2177 }
2178 for ( int32_t q = 0; q < 2; q++ )
2179 {
2180 initA[q] = other.initA[q];
2181 weap_initiala[q] = other.weap_initiala[q];
2182 }
2183 }
2184
2185 esPatra::esPatra(esPatra const & other, bool new_script_uid, bool clear_parent_script_UID):
2186 //Struct Element Type Purpose
2187 //sprite(other),
2188 enemy(other)
2189
2190 {
2191
2192 //arrays
2193
2194 if(other.scrmem)
2195 {
2196 alloc_scriptmem();
2197 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2198
2199 scrmem->scriptData = other.scrmem->scriptData;
2200 }
2201 else scrmem = NULL;
2202 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2203 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2204
2205 for ( int32_t q = 0; q < 255; q++ )
2206 {
2207 nx[q] = other.nx[q];
2208 ny[q] = other.ny[q];
2209 nxoffset[q] = other.nxoffset[q];
2210 nyoffset[q] = other.nyoffset[q];
2211 }
2212
2213 for(int32_t i=0; i<edefLAST255; i++)
2214 defense[i]=other.defense[i];
2215 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2216 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2217
2218 if(new_script_uid)
2219 {
2220 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2221 }
2222 if(clear_parent_script_UID)
2223 {
2224 parent_script_UID = 0;
2225 }
2226 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2227 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2228
2229 for ( int32_t q = 0; q < 8; q++ )
2230 {
2231 initD[q] = other.initD[q];
2232 weap_initiald[q] = other.weap_initiald[q];
2233 }
2234 for ( int32_t q = 0; q < 2; q++ )
2235 {
2236 initA[q] = other.initA[q];
2237 weap_initiala[q] = other.weap_initiala[q];
2238 }
2239 }
2240
2241 esPatraBS::esPatraBS(esPatraBS const & other, bool new_script_uid, bool clear_parent_script_UID):
2242 //Struct Element Type Purpose
2243 //sprite(other),
2244 enemy(other)
2245
2246 {
2247
2248 //arrays
2249
2250 if(other.scrmem)
2251 {
2252 alloc_scriptmem();
2253 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2254
2255 scrmem->scriptData = other.scrmem->scriptData;
2256 }
2257 else scrmem = NULL;
2258 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2259 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2260
2261 for ( int32_t q = 0; q < 255; q++ )
2262 {
2263 nx[q] = other.nx[q];
2264 ny[q] = other.ny[q];
2265 nxoffset[q] = other.nxoffset[q];
2266 nyoffset[q] = other.nyoffset[q];
2267 }
2268
2269 for(int32_t i=0; i<edefLAST255; i++)
2270 defense[i]=other.defense[i];
2271 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2272 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2273
2274 if(new_script_uid)
2275 {
2276 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2277 }
2278 if(clear_parent_script_UID)
2279 {
2280 parent_script_UID = 0;
2281 }
2282 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2283 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2284
2285 for ( int32_t q = 0; q < 8; q++ )
2286 {
2287 initD[q] = other.initD[q];
2288 weap_initiald[q] = other.weap_initiald[q];
2289 }
2290 for ( int32_t q = 0; q < 2; q++ )
2291 {
2292 initA[q] = other.initA[q];
2293 weap_initiala[q] = other.weap_initiala[q];
2294 }
2295 }
2296
2297 */
2298
2299
5/10
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 148 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 148 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 148 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 148 times.
✗ Branch 9 not taken.
444 enemy::enemy(zfix X,zfix Y,int32_t Id,int32_t Clk) : sprite()
2300 296 {
2301
1/2
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
148 x=X;
2302
1/2
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
148 y=Y;
2303 148 id=Id;
2304 148 clk=Clk;
2305
1/2
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
148 floor_y=y;
2306 148 ceiling=false;
2307 148 fading = misc = clk2 = clk3 = stunclk = hclk = sclk = superman = 0;
2308 148 grumble = movestatus = posframe = timer = ox = oy = 0;
2309
4/8
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 148 times.
✓ Branch 4 taken 148 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 148 times.
✗ Branch 7 not taken.
148 yofs = (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) - ((isSideViewGravity()) ? 0 : 2);
2310 148 did_armos=true;
2311 148 script_spawned=false;
2312
2313 148 d = guysbuf + (id & 0xFFF);
2314 148 hp = d->hp;
2315 148 starting_hp = hp;
2316 // cs = d->cset;
2317 //d variables
2318
2319 148 flags=d->flags;
2320 148 flags2=d->flags2;
2321 148 s_tile=d->s_tile; //secondary (additional) tile(s)
2322 148 family=d->family;
2323 148 dcset=d->cset;
2324 148 cs=dcset;
2325
3/4
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 109 times.
148 anim=get_bit(quest_rules,qr_NEWENEMYTILES)?d->e_anim:d->anim;
2326 148 dp=d->dp;
2327 148 wdp=d->wdp;
2328 148 wpn=d->weapon;
2329 148 wpnsprite = d-> wpnsprite; //2.6 -Z
2330 148 rate=d->rate;
2331 148 hrate=d->hrate;
2332
1/2
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
148 dstep=d->step;
2333 148 homing=d->homing;
2334 148 dmisc1=d->misc1;
2335 148 dmisc2=d->misc2;
2336 148 dmisc3=d->misc3;
2337 148 dmisc4=d->misc4;
2338 148 dmisc5=d->misc5;
2339 148 dmisc6=d->misc6;
2340 148 dmisc7=d->misc7;
2341 148 dmisc8=d->misc8;
2342 148 dmisc9=d->misc9;
2343 148 dmisc10=d->misc10;
2344 148 dmisc11=d->misc11;
2345 148 dmisc12=d->misc12;
2346 148 dmisc13=d->misc13;
2347 148 dmisc14=d->misc14;
2348 148 dmisc15=d->misc15;
2349 148 dmisc16=d->misc16;
2350 148 dmisc17=d->misc17;
2351 148 dmisc18=d->misc18;
2352 148 dmisc19=d->misc19;
2353 148 dmisc20=d->misc20;
2354 148 dmisc21=d->misc21;
2355 148 dmisc22=d->misc22;
2356 148 dmisc23=d->misc23;
2357 148 dmisc24=d->misc24;
2358 148 dmisc25=d->misc25;
2359 148 dmisc26=d->misc26;
2360 148 dmisc27=d->misc27;
2361 148 dmisc28=d->misc28;
2362 148 dmisc29=d->misc29;
2363 148 dmisc30=d->misc30;
2364 148 dmisc31=d->misc31;
2365 148 dmisc32=d->misc32;
2366
3/4
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 109 times.
✓ Branch 3 taken 39 times.
148 if (get_bit(quest_rules, qr_BROKEN_ATTRIBUTE_31_32))
2367 {
2368 109 dmisc31 = dmisc32;
2369 109 dmisc32 = 0;
2370 109 }
2371 148 spr_shadow=d->spr_shadow;
2372 148 spr_death=d->spr_death;
2373 148 spr_spawn=d->spr_spawn;
2374
2375
2/2
✓ Branch 0 taken 6068 times.
✓ Branch 1 taken 148 times.
6216 for(int32_t i=0; i<edefLAST255; i++)
2376 6068 defense[i]=d->defense[i];
2377
2378 148 bgsfx=d->bgsfx;
2379 148 hitsfx=d->hitsfx;
2380 148 deadsfx=d->deadsfx;
2381 148 bosspal=d->bosspal;
2382 148 parent_script_UID = 0;
2383
2384 148 frozentile = d->frozentile;
2385
2386 148 frozencset = d->frozencset;
2387 148 frozenclock = 0;
2388
2/2
✓ Branch 0 taken 1480 times.
✓ Branch 1 taken 148 times.
1628 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = d->frozenmisc[q];
2389
2390
2/2
✓ Branch 0 taken 148 times.
✓ Branch 1 taken 2368 times.
2516 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = 0;
2391 //firesfx = 0; //t.b.a -Z
2392 148 isCore = true; //t.b.a
2393 148 parentCore = 0; //t.b.a
2394
1/2
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
148 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2395
2396 148 firesfx = d->firesfx;
2397
2/2
✓ Branch 0 taken 4736 times.
✓ Branch 1 taken 148 times.
4884 for ( int32_t q = 0; q < 32; q++ ) movement[q] = d->movement[q];
2398
2/2
✓ Branch 0 taken 4736 times.
✓ Branch 1 taken 148 times.
4884 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = d->new_weapon[q];
2399
2400
1/2
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
148 script = (d->script >= 0) ? d->script : 0; //Dont assign invalid data.
2401 148 waitdraw = 0;
2402
1/2
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
148 weaponscript = (d->weaponscript >= 0) ? d->weaponscript : 0; //Dont assign invalid data.
2403
2404
2/2
✓ Branch 0 taken 1184 times.
✓ Branch 1 taken 148 times.
1332 for ( int32_t q = 0; q < 8; q++ )
2405 {
2406 1184 initD[q] = d->initD[q];
2407 //Z_scripterrlog("(enemy::enemy(zfix)): Loading weapon InitD[%d] to an enemy with a value of (%d)\n",q,d->weap_initiald[q]);
2408 1184 weap_initiald[q] = d->weap_initiald[q];
2409 //al_trace("Guys.cpp: Assigning guy.initD[%d]: %d\n",q, d->initD.initD[q]);
2410 //al_trace("Guys.cpp: Assigning guy.initD[%d] from d->initD[%d]: %d\n",q,q, d->initD[q]);
2411 //al_trace("Guys.cpp: guy.initD[%d] is: %d\n",q, initD[q]);
2412 1184 }
2413
2/2
✓ Branch 0 taken 296 times.
✓ Branch 1 taken 148 times.
444 for ( int32_t q = 0; q < 2; q++ )
2414 {
2415 296 initA[q] = d->initA[q];
2416 296 weap_initiala[q] = d->weap_initiala[q];
2417 296 }
2418
2419 148 stickclk = 0;
2420 148 submerged = false;
2421 148 ffcactivated = 0;
2422 148 hitdir = -1;
2423 148 dialogue_str = 0; //set by spawn flags.
2424 148 editorflags = d->editorflags; //set by Enemy Editor
2425 //Set the drawing flag for this sprite.
2426
1/2
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
148 if ( (editorflags&ENEMY_FLAG12) ) { drawflags |= sprdrawflagALWAYSOLDDRAWS; }
2427
2428
2429
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 147 times.
148 if(bosspal>-1)
2430 {
2431
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 loadpalset(csBOSS,pSprite(bosspal));
2432 1 }
2433
2434
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 108 times.
148 if(bgsfx>-1)
2435 {
2436
1/2
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
40 cont_sfx(bgsfx);
2437 40 }
2438
2439
3/4
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 109 times.
148 if(get_bit(quest_rules,qr_NEWENEMYTILES))
2440 {
2441 39 o_tile=d->e_tile;
2442 39 frate = d->e_frate;
2443 39 }
2444 else
2445 {
2446 109 o_tile=d->tile;
2447 109 frate = d->frate;
2448 }
2449
2450 148 tile=0; //init to 0 here, but set it later.
2451
2452 148 scripttile = -1;
2453 148 scriptflip = -1;
2454 148 do_animation = 1;
2455 148 immortal = false;
2456 148 noSlide = false;
2457 148 deathexstate = -1;
2458
2459 148 hashero=false;
2460
2461 // If they forgot the invisibility flag, here's another failsafe:
2462
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 146 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
148 if(o_tile==0 && family!=eeSPINTILE)
2463 2 flags |= guy_invisible;
2464
2465 // step = d->step/100.0;
2466 // To preserve the odd step values for Keese & Gleeok heads. -L
2467
5/8
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 148 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17 times.
✓ Branch 5 taken 131 times.
✓ Branch 6 taken 17 times.
✗ Branch 7 not taken.
148 if(dstep==62.0) dstep+=0.5;
2468
3/8
✓ Branch 0 taken 131 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 131 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 131 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
131 else if(dstep==89) dstep-=1/9;
2469
2470
5/10
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 148 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 148 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 148 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 148 times.
✗ Branch 9 not taken.
148 step = zslongToFix(dstep*100);
2471
2472
2473 148 item_set = d->item_set;
2474 148 grumble = d->grumble;
2475
2476
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 24 times.
148 if(frate == 0)
2477 24 frate = 256;
2478
2479 148 leader = itemguy = dying = scored = false;
2480 148 canfreeze = count_enemy = true;
2481 148 mainguy = !(flags & guy_doesntcount);
2482
1/2
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
148 dir = zc_oldrand()&3;
2483
2484 //2.6 Enemy Editor Hit and TIle Sizes
2485
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
148 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && d->txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
2486 //al_trace("->txsz:%i\n", d->txsz); Verified that this is setting the value. -Z
2487 // al_trace("Enemy txsz:%i\n", txsz);
2488
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
148 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && d->tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
2489
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
148 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
2490
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
148 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && d->hysz >= 0 ) hysz = d->hysz;
2491
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
148 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && d->hzsz >= 0 ) hzsz = d->hzsz;
2492
1/2
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
148 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
2493
1/2
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
148 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
2494 // if ( (d->SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = d->hzofs;
2495
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
148 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
2496
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 148 times.
148 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
2497 {
2498 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
2499 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
2500 }
2501
2502
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
148 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
2503
2504 148 SIZEflags = d->SIZEflags;
2505
2506
2/10
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 148 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
148 if((wpn==ewBomb || wpn==ewSBomb) && family!=eeOTHER && family!=eeFIRE && (family!=eeWALK || dmisc2 != e2tBOMBCHU))
2507 wpn = 0;
2508
2509 //tile should never be 0 after init --Z (failsafe)
2510
4/6
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 148 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 109 times.
✓ Branch 5 taken 39 times.
148 if (tile <= 0 && FFCore.getQuestHeaderInfo(vZelda) >= 0x255) {tile = o_tile;}
2511
2512 //Moveflags; for gravity and pit interaction
2513 148 moveflags = d->moveflags;
2514
3/4
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 133 times.
✓ Branch 3 taken 15 times.
148 if(!can_pitfall(false))
2515 {
2516 //Some enemies must not interact with pits. Force their flags, for sanity's sake.
2517 15 moveflags &= ~FLAG_CAN_PITFALL;
2518 15 moveflags &= ~FLAG_CAN_WATERDROWN;
2519 15 }
2520
2521
1/2
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
148 shieldCanBlock = get_bit(quest_rules,qr_GOHMA_UNDAMAGED_BUG)?true:false;
2522 148 }
2523
2524 //base clone constructor
2525
2526 enemy::enemy(enemy const & other, bool new_script_uid, bool clear_parent_script_UID):
2527 //Struct Element Type Purpose
2528 sprite(other),
2529 //x(other.x), //int32_t
2530 //y(other.y), //int32_t
2531 //id(other.id), //int32_t
2532 //clk(other.clk), //int32_t
2533 floor_y(other.floor_y), //int32_t
2534 fading(other.fading), //int32_t
2535 //misc(other.misc), //int32_t
2536 clk2(other.clk2), //int32_t
2537 clk3(other.clk3), //int32_t
2538 stunclk(other.stunclk), //int32_t
2539 hclk(other.hclk), //int32_t
2540 sclk(other.sclk), //int32_t
2541 superman(other.superman), //int32_t
2542 //grumble(other.grumble), //int32_t
2543 movestatus(other.movestatus), //int32_t
2544 posframe(other.posframe), //int32_t
2545 timer(other.timer), //int32_t
2546 ox(other.ox), //int32_t
2547 oy(other.oy), //int32_t
2548 //yofs(other.yofs), //int32_t
2549 did_armos(other.did_armos), //int32_t
2550 script_spawned(other.script_spawned), //int32_t
2551 d(other.d), //int32_t
2552 hp(other.hp), //int32_t
2553 starting_hp(other.starting_hp), //int32_t
2554 //flags(other.flags), //int32_t
2555
2556 flags2(other.flags2), //int32_t
2557 s_tile(other.s_tile), //int32_t
2558 family(other.family), //int32_t
2559 dcset(other.dcset), //int32_t
2560 //cs(other.cs), //int32_t
2561 anim(other.anim), //int32_t
2562 dp(other.dp), //int32_t
2563 wdp(other.wdp), //int32_t
2564 wpnsprite(other.wpnsprite), //int32_t
2565 rate(other.rate), //int32_t
2566 hrate(other.hrate), //int32_t
2567 dstep(other.dstep), //int32_t
2568
2569 homing(other.homing), //int32_t
2570 dmisc1(other.dmisc1), //int32_t
2571 dmisc2(other.dmisc2), //int32_t
2572 dmisc3(other.dmisc3), //int32_t
2573 dmisc4(other.dmisc4), //int32_t
2574 dmisc5(other.dmisc5), //int32_t
2575 dmisc6(other.dmisc6), //int32_t
2576 dmisc7(other.dmisc7), //int32_t
2577 dmisc8(other.dmisc8), //int32_t
2578 dmisc9(other.dmisc9), //int32_t
2579 dmisc10(other.dmisc10), //int32_t
2580 dmisc11(other.dmisc11), //int32_t
2581 dmisc12(other.dmisc12), //int32_t
2582 dmisc13(other.dmisc13), //int32_t
2583 dmisc14(other.dmisc14), //int32_t
2584 dmisc15(other.dmisc15), //int32_t
2585 dmisc16(other.dmisc16), //int32_t
2586 dmisc17(other.dmisc17), //int32_t
2587 dmisc18(other.dmisc18), //int32_t
2588 dmisc19(other.dmisc19), //int32_t
2589 dmisc20(other.dmisc20), //int32_t
2590 dmisc21(other.dmisc21), //int32_t
2591 dmisc22(other.dmisc22), //int32_t
2592 dmisc23(other.dmisc23), //int32_t
2593 dmisc24(other.dmisc24), //int32_t
2594 dmisc25(other.dmisc25), //int32_t
2595 dmisc26(other.dmisc26), //int32_t
2596 dmisc27(other.dmisc27), //int32_t
2597 dmisc28(other.dmisc28), //int32_t
2598 dmisc29(other.dmisc29), //int32_t
2599 dmisc30(other.dmisc30), //int32_t
2600 dmisc31(other.dmisc31), //int32_t
2601 dmisc32(other.dmisc32), //int32_t
2602 bgsfx(other.bgsfx), //int32_t
2603 hitsfx(other.hitsfx), //int32_t
2604 deadsfx(other.deadsfx), //int32_t
2605 bosspal(other.bosspal), //int32_t
2606 parent_script_UID(other.parent_script_UID), //int32_t
2607 frozentile(other.frozentile), //int32_t
2608 frozencset(other.frozencset), //int32_t
2609 frozenclock(other.frozenclock), //int32_t
2610 isCore(other.isCore), //int32_t
2611 parentCore(other.parentCore), //int32_t
2612 script_UID(other.script_UID), //int32_t
2613 firesfx(other.firesfx), //int32_t
2614 //script(other.script), //int32_t
2615 //waitdraw(other.waitdraw), //int32_t
2616 weaponscript(other.weaponscript), //int32_t
2617 stickclk(other.stickclk), //int32_t
2618 hitdir(other.hitdir), //int32_t
2619 submerged(other.submerged), //int32_t
2620 ffcactivated(other.ffcactivated), //word
2621
2622 dialogue_str(other.dialogue_str), //int32_t
2623 editorflags(other.editorflags), //int32_t
2624 //drawflags(other.drawflags), //int32_t
2625 o_tile(other.o_tile), //int32_t
2626 frate(other.frate), //int32_t
2627 //tile(other.tile), //int32_t
2628 //scripttile(other.scripttile), //int32_t
2629 //scriptflip(other.scriptflip), //int32_t
2630 //do_animation(other.do_animation), //int32_t
2631 immortal(other.immortal), //bool
2632 noSlide(other.noSlide), //bool
2633 deathexstate(other.deathexstate), //int32_t
2634 flags(other.flags), //int32_t
2635 step(other.step), //int32_t
2636
2637 item_set(other.item_set), //int32_t
2638 grumble(other.grumble), //int32_t
2639 leader(other.leader), //int32_t
2640 itemguy(other.itemguy), //int32_t
2641 dying(other.dying), //int32_t
2642 scored(other.scored), //int32_t
2643 //canfreeze(other.canfreeze), //int32_t
2644 count_enemy(other.count_enemy), //int32_t
2645 mainguy(other.mainguy), //int32_t
2646 //dir(other.dir), //int32_t
2647
2648 //txsz(other.txsz), //int32_t
2649 //tysz(other.tysz), //int32_t
2650 //hxsz(other.hxsz), //int32_t
2651 //hysz(other.hysz), //int32_t
2652 //hzsz(other.hzsz), //int32_t
2653 //hxofs(other.hxofs), //int32_t
2654 //hxofs(other.hxofs), //int32_t
2655 //xofs(other.xofs), //int32_t
2656 //yofs(other.yofs), //int32_t
2657 //hzofs(other.hzofs), //int32_t
2658 //zofs(other.zofs), //int32_t
2659
2660 wpn(other.wpn), //int32_t
2661 SIZEflags(other.SIZEflags), //int32_t
2662 hashero(other.hashero)
2663
2664 {
2665
2666 //arrays
2667
2668 if(other.scrmem)
2669 {
2670 alloc_scriptmem();
2671 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2672
2673 scrmem->scriptData = other.scrmem->scriptData;
2674 }
2675 else scrmem = NULL;
2676 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2677 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2678
2679 for(int32_t i=0; i<edefLAST255; i++)
2680 defense[i]=other.defense[i];
2681 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2682 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2683
2684 if(new_script_uid)
2685 {
2686 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2687 }
2688 if(clear_parent_script_UID)
2689 {
2690 parent_script_UID = 0;
2691 }
2692 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2693 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2694
2695 for ( int32_t q = 0; q < 8; q++ )
2696 {
2697 initD[q] = other.initD[q];
2698 weap_initiald[q] = other.weap_initiald[q];
2699 }
2700 for ( int32_t q = 0; q < 2; q++ )
2701 {
2702 initA[q] = other.initA[q];
2703 weap_initiala[q] = other.weap_initiala[q];
2704 }
2705 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
2706 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
2707 // al_trace("Enemy txsz:%i\n", txsz);
2708 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = tysz; if ( tysz > 1 ) extend = 3; }
2709 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = hxsz;
2710 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = hysz;
2711 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = hzsz;
2712 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = hxofs;
2713 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = hyofs;
2714 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
2715 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)xofs;
2716 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
2717 {
2718 yofs = (int32_t)yofs; //This seems to be setting to +48 or something with any value set?! -Z
2719 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
2720 }
2721
2722 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
2723
2724
2725
2726
2727 }
2728
2729
2730 int32_t enemy::getScriptUID() { return script_UID; }
2731 void enemy::setScriptUID(int32_t new_id) { script_UID = new_id; }
2732 145 enemy::~enemy()
2733 145 {
2734
2/4
✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 145 times.
✗ Branch 3 not taken.
145 FFCore.deallocateAllArrays(SCRIPT_NPC, getUID());
2735 145 }
2736
2737
2738 bool enemy::is_move_paused()
2739 {
2740 return (clk<0 || dying || stunclk || watch || ceiling || frozenclock || fallclk || drownclk);
2741 }
2742
2743 2778 bool enemy::scr_walkflag(int32_t dx,int32_t dy,int32_t special, int32_t dir, int32_t input_x, int32_t input_y, bool kb)
2744 {
2745 2778 int32_t yg = (special==spw_floater)?8:0;
2746 2778 int32_t nb = get_bit(quest_rules, qr_NOBORDER) ? 16 : 0;
2747 //Z_eventlog("Checking x,y %d,%d\n",dx,dy);
2748
1/2
✓ Branch 0 taken 2778 times.
✗ Branch 1 not taken.
2778 if(input_x == -1000)
2749 input_x = dx;
2750
1/2
✓ Branch 0 taken 2778 times.
✗ Branch 1 not taken.
2778 if(input_y == -1000)
2751 input_y = dy;
2752
2753
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2778 times.
5556 if(!(moveflags & FLAG_IGNORE_SCREENEDGE)
2754
3/6
✓ Branch 0 taken 2778 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2778 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2778 times.
2778 && (input_x<16-nb || input_y<zc_max(16-yg-nb,0)
2755
2/4
✓ Branch 0 taken 2778 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2778 times.
✗ Branch 3 not taken.
2778 || input_x>=240+nb-hxsz || input_y>=160+nb-hysz))
2756 return true;
2757
2758
3/6
✓ Branch 0 taken 2778 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2778 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2778 times.
✗ Branch 5 not taken.
2778 if(!(moveflags & FLAG_CAN_PITWALK) && (!(moveflags & FLAG_CAN_PITFALL) || !kb)) //Don't walk into pits, unless being knocked back
2759 {
2760 if(ispitfall(dx,dy))
2761 return true;
2762 }
2763
2764 2778 bool flying = false;
2765 2778 bool cansolid = false;
2766
1/2
✓ Branch 0 taken 2778 times.
✗ Branch 1 not taken.
2778 if(moveflags & FLAG_IGNORE_SOLIDITY)
2767 cansolid = true;
2768
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2778 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2778 switch(special)
2769 {
2770 case spw_clipbottomright:
2771 if(dy>=128 || dx>=208) return true;
2772 break;
2773 case spw_clipright:
2774 break; //if(input_x>=208) return true; break;
2775
2776 case spw_wizzrobe: // fall through
2777 case spw_floater: // Special case for fliers and wizzrobes - hack!
2778 {
2779 if(isdungeon() && !(moveflags & FLAG_IGNORE_SCREENEDGE))
2780 {
2781 if(dy < 32-yg || dy >= 144) return true;
2782 if(dx < 32 || dx >= 224) return true;
2783 }
2784 if(!(moveflags & FLAG_IGNORE_BLOCKFLAGS) && flyerblocked(dx, dy, special, kb))
2785 return true;
2786 cansolid = true;
2787 flying = true;
2788 }
2789 }
2790
2791 2778 dx &= ~7;
2792 2778 dy &= ~7;
2793
2794
3/6
✓ Branch 0 taken 2778 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2778 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2778 times.
✗ Branch 5 not taken.
2778 if(!flying && !(moveflags & FLAG_IGNORE_BLOCKFLAGS) && groundblocked(dx,dy,kb)) return true;
2795
2796
4/8
✓ Branch 0 taken 2778 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2778 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2778 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2778 times.
2778 if (dx < 0 || dx > 255 || dy < 0 || dy > 175)
2797 return false;
2798 //_walkflag code
2799 mapscr *s1, *s2;
2800 2778 s1=(((*tmpscr).layermap[0]-1)>=0)?tmpscr2:NULL;
2801 2778 s2=(((*tmpscr).layermap[1]-1)>=0)?tmpscr2+1:NULL;
2802
2803 2778 int32_t cpos=(dx>>4)+(dy&0xF0);
2804
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2778 times.
✓ Branch 2 taken 1983 times.
✓ Branch 3 taken 795 times.
2778 int32_t ci = tmpscr->data[cpos], ci1 = (s1?s1:tmpscr)->data[cpos], ci2 = (s2?s2:tmpscr)->data[cpos];
2805 2778 newcombo const& c = combobuf[ci];
2806 2778 newcombo const& c1 = combobuf[ci1];
2807 2778 newcombo const& c2 = combobuf[ci2];
2808
2809 2778 int32_t b=1;
2810
2/2
✓ Branch 0 taken 1346 times.
✓ Branch 1 taken 1432 times.
2778 if(dx&8) b<<=2;
2811
2/2
✓ Branch 0 taken 1347 times.
✓ Branch 1 taken 1431 times.
2778 if(dy&8) b<<=1;
2812
2813 #define iwtr(cmb, x, y, shallow) \
2814 (shallow \
2815 ? iswaterex(cmb, currmap, currscr, -1, dx, dy, false, false, false, true, false) \
2816 && !iswaterex(cmb, currmap, currscr, -1, dx, dy, false, false, false, false, false) \
2817 : iswaterex(cmb, currmap, currscr, -1, dx, dy, false, false, false, false, false))
2818 2778 bool wtr = iwtr(ci, dx, dy, false);
2819
1/2
✓ Branch 0 taken 2778 times.
✗ Branch 1 not taken.
2778 bool shwtr = iwtr(ci, dx, dy, true);
2820 2778 bool pit = ispitfall(dx,dy);
2821
2822
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2778 times.
✓ Branch 2 taken 2778 times.
✗ Branch 3 not taken.
2778 bool canwtr = (moveflags & FLAG_CAN_WATERWALK) || ((moveflags & FLAG_CAN_WATERDROWN) && kb);
2823
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2778 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2778 times.
2778 bool canpit = (moveflags & FLAG_CAN_PITWALK) || ((moveflags & FLAG_CAN_PITFALL) && kb);
2824 2778 bool needwtr = (moveflags & FLAG_ONLY_WATERWALK);
2825 2778 bool needshwtr = (moveflags & FLAG_ONLY_SHALLOW_WATERWALK);
2826 2778 bool needpit = (moveflags & FLAG_ONLY_PITWALK);
2827
2828 2778 int32_t cwalkflag = c.walk & 0xF;
2829
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2778 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2778 if (c.type == cBRIDGE && get_bit(quest_rules, qr_OLD_BRIDGE_COMBOS)) cwalkflag = 0;
2830
1/2
✓ Branch 0 taken 2778 times.
✗ Branch 1 not taken.
2778 if (s1)
2831 {
2832 if (c1.type == cBRIDGE)
2833 {
2834 if (!get_bit(quest_rules, qr_OLD_BRIDGE_COMBOS))
2835 {
2836 int efflag = (c1.walk & 0xF0)>>4;
2837 int newsolid = (c1.walk & 0xF);
2838 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
2839 }
2840 else cwalkflag &= c1.walk;
2841 }
2842 else cwalkflag |= c1.walk & 0xF;
2843 }
2844
2/2
✓ Branch 0 taken 795 times.
✓ Branch 1 taken 1983 times.
2778 if (s2)
2845 {
2846
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1983 times.
1983 if (c2.type == cBRIDGE)
2847 {
2848 if (!get_bit(quest_rules, qr_OLD_BRIDGE_COMBOS))
2849 {
2850 int efflag = (c2.walk & 0xF0)>>4;
2851 int newsolid = (c2.walk & 0xF);
2852 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
2853 }
2854 else cwalkflag &= c2.walk;
2855 }
2856 1983 else cwalkflag |= c2.walk & 0xF;
2857 1983 }
2858 2778 bool solid = cwalkflag & b;
2859
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 2523 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 255 times.
2778 if (solid && !cansolid) return true;
2860
3/6
✓ Branch 0 taken 2523 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2523 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2523 times.
2523 if(needwtr || needshwtr || needpit)
2861 {
2862 bool ret = true;
2863 if (needwtr && wtr) ret = false;
2864 else if (needshwtr && shwtr) ret = false;
2865 else if (needpit && pit) ret = false;
2866 return ret;
2867 }
2868
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2523 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2523 else if(wtr && !canwtr)
2869 return true;
2870
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2523 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2523 else if(pit && !canpit)
2871 return true;
2872
2873 2523 return false;
2874 2778 }
2875
2876 1096 bool enemy::scr_canmove(zfix dx, zfix dy, int32_t special, bool kb, bool ign_sv)
2877 {
2878
3/4
✓ Branch 0 taken 632 times.
✓ Branch 1 taken 464 times.
✓ Branch 2 taken 632 times.
✗ Branch 3 not taken.
1096 if(!(dx || dy)) return true;
2879 1096 zfix bx = x+hxofs, by = y+hyofs; //left/top
2880 1096 zfix rx = bx+hxsz-1, ry = by+hysz-1; //right/bottom
2881
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1096 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1096 if(!ign_sv && dy < 0) //check gravity
2882 {
2883 if((moveflags & FLAG_OBEYS_GRAV) && isSideViewGravity())
2884 return false;
2885 }
2886
2887
3/4
✓ Branch 0 taken 464 times.
✓ Branch 1 taken 632 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 464 times.
1096 if(dx && !dy)
2888 {
2889
2/2
✓ Branch 0 taken 203 times.
✓ Branch 1 taken 261 times.
464 if(dx < 0)
2890 {
2891
2/4
✓ Branch 0 taken 203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 203 times.
203 special = (special==spw_clipbottomright||special==spw_clipright)?spw_none:special;
2892 203 int32_t tx = (bx+dx).getFloor();
2893
2/2
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 203 times.
609 for(zfix ty = 0; by+ty < ry; ty += 8)
2894 {
2895
1/2
✓ Branch 0 taken 406 times.
✗ Branch 1 not taken.
406 if(scr_walkflag(tx, by+ty, special, left, bx, by, kb))
2896 return false;
2897 406 }
2898
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 203 times.
203 if(scr_walkflag(tx, ry, special, left, bx, by, kb))
2899 return false;
2900 203 }
2901 else
2902 {
2903 261 int32_t tx = (rx+dx).getCeil();
2904
2/2
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 261 times.
783 for(zfix ty = 0; by+ty < ry; ty += 8)
2905 {
2906
1/2
✓ Branch 0 taken 522 times.
✗ Branch 1 not taken.
522 if(scr_walkflag(tx, by+ty, special, right, bx, by, kb))
2907 return false;
2908 522 }
2909
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
261 if(scr_walkflag(tx, ry, special, right, bx, by, kb))
2910 return false;
2911 }
2912 464 }
2913
2/4
✓ Branch 0 taken 632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 632 times.
632 else if(dy && !dx)
2914 {
2915
2/2
✓ Branch 0 taken 325 times.
✓ Branch 1 taken 307 times.
632 if(dy < 0)
2916 {
2917
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 special = (special==spw_clipbottomright)?spw_none:special;
2918 325 int32_t ty = (by+dy).getFloor();
2919
2/2
✓ Branch 0 taken 650 times.
✓ Branch 1 taken 325 times.
975 for(zfix tx = 0; bx+tx < rx; tx += 8)
2920 {
2921
1/2
✓ Branch 0 taken 650 times.
✗ Branch 1 not taken.
650 if(scr_walkflag(bx+tx, ty, special, up, bx, by, kb))
2922 return false;
2923 650 }
2924
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 if(scr_walkflag(rx, ty, special, up, bx, by, kb))
2925 return false;
2926 325 }
2927 else
2928 {
2929 307 int32_t ty = (ry+dy).getCeil();
2930
2/2
✓ Branch 0 taken 359 times.
✓ Branch 1 taken 52 times.
411 for(zfix tx = 0; bx+tx < rx; tx += 8)
2931 {
2932
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 255 times.
359 if(scr_walkflag(bx+tx, ty, special, down, bx, by, kb))
2933 255 return false;
2934 104 }
2935
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 if(scr_walkflag(rx, ty, special, down, bx, by, kb))
2936 return false;
2937 }
2938 377 }
2939 else
2940 {
2941 return scr_canmove(dx, 0, special, kb, ign_sv) && scr_canmove(dy, 0, special, kb, ign_sv);
2942 }
2943 841 return true;
2944 1096 }
2945
2946 bool enemy::scr_canplace(zfix dx, zfix dy, int32_t special, bool kb)
2947 {
2948 zfix bx = dx+hxofs, by = dy+hyofs; //left/top
2949 zfix rx = bx+hxsz-1, ry = by+hysz-1; //right/bottom
2950
2951 for(zfix ty = 0; by+ty < ry; ty += 8)
2952 {
2953 for(zfix tx = 0; bx+tx < rx; tx += 8)
2954 {
2955 if(scr_walkflag(bx+tx, by+ty, special, -1, -1000, -1000, kb))
2956 return false;
2957 }
2958 if(scr_walkflag(rx, by+ty, special, -1, -1000, -1000, kb))
2959 return false;
2960 }
2961 for(zfix tx = 0; bx+tx < rx; tx += 8)
2962 {
2963 if(scr_walkflag(bx+tx, ry, special, -1, -1000, -1000, kb))
2964 return false;
2965 }
2966 if(scr_walkflag(rx, ry, special, -1, -1000, -1000, kb))
2967 return false;
2968 return true;
2969 }
2970
2971 897 bool enemy::movexy(zfix dx, zfix dy, int32_t special, bool kb, bool ign_sv)
2972 {
2973 897 bool ret = true;
2974
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 897 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
897 if(!ign_sv && dy < 0 && (moveflags & FLAG_OBEYS_GRAV) && isSideViewGravity())
2975 dy = 0;
2976
4/4
✓ Branch 0 taken 919 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 897 times.
✓ Branch 3 taken 29 times.
926 while(abs(dx) > 8 || abs(dy) > 8)
2977 {
2978
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 25 times.
29 if(abs(dx) > abs(dy))
2979 {
2980 4 int32_t tdx = dx.sign() * 8;
2981
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(movexy(tdx, 0, special, kb, ign_sv))
2982 4 dx -= tdx;
2983 else
2984 {
2985 dx = tdx;
2986 ret = false;
2987 }
2988 4 }
2989 else
2990 {
2991 25 int32_t tdy = dy.sign() * 8;
2992
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 24 times.
25 if(movexy(0, tdy, special, kb, ign_sv))
2993 1 dy -= tdy;
2994 else
2995 {
2996 24 dy = tdy;
2997 24 ret = false;
2998 }
2999 }
3000 }
3001
2/2
✓ Branch 0 taken 433 times.
✓ Branch 1 taken 464 times.
897 if(dx)
3002 {
3003
1/2
✓ Branch 0 taken 464 times.
✗ Branch 1 not taken.
464 if(scr_canmove(dx, 0, special, kb, ign_sv))
3004 464 x += dx;
3005 else
3006 {
3007 ret = false;
3008 int32_t xsign = dx.sign();
3009 while(scr_canmove(xsign, 0, special, kb, ign_sv))
3010 {
3011 x += xsign;
3012 dx -= xsign;
3013 }
3014 if(scr_canmove(dx.decsign(), 0, special, kb, ign_sv)) //can move 0.0001 to 0.9999 px in this direction
3015 {
3016 if(dx > 0)
3017 x.doCeil();
3018 else x.doFloor();
3019 }
3020 }
3021 464 }
3022
2/2
✓ Branch 0 taken 435 times.
✓ Branch 1 taken 462 times.
897 if(dy)
3023 {
3024
2/2
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 85 times.
462 if(scr_canmove(0, dy, special, kb, ign_sv))
3025 377 y += dy;
3026 else
3027 {
3028 85 ret = false;
3029 85 int32_t ysign = dy.sign();
3030
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 85 times.
85 while(scr_canmove(0, ysign, special, kb, ign_sv))
3031 {
3032 y += ysign;
3033 dy -= ysign;
3034 }
3035
1/2
✓ Branch 0 taken 85 times.
✗ Branch 1 not taken.
85 if(scr_canmove(0, dy.decsign(), special, kb, ign_sv)) //can move 0.0001 to 0.9999 px in this direction
3036 {
3037 if(dy > 0)
3038 y.doCeil();
3039 else y.doFloor();
3040 }
3041 }
3042 462 }
3043 897 return ret;
3044 }
3045
3046 bool enemy::moveDir(int32_t dir, zfix px, int32_t special, bool kb)
3047 {
3048 zfix diagrate = zslongToFix(7071);
3049 switch(NORMAL_DIR(dir))
3050 {
3051 case up:
3052 return movexy(0, -px, special, kb);
3053 case down:
3054 return movexy(0, px, special, kb);
3055 case left:
3056 return movexy(-px, 0, special, kb);
3057 case right:
3058 return movexy(px, 0, special, kb);
3059 case r_up:
3060 return movexy(px*diagrate, -px*diagrate, special, kb);
3061 case r_down:
3062 return movexy(px*diagrate, px*diagrate, special, kb);
3063 case l_up:
3064 return movexy(-px*diagrate, -px*diagrate, special, kb);
3065 case l_down:
3066 return movexy(-px*diagrate, px*diagrate, special, kb);
3067 }
3068 return false;
3069 }
3070
3071 bool enemy::moveAtAngle(zfix degrees, zfix px, int32_t special, bool kb)
3072 {
3073 double v = degrees.getFloat() * PI / 180.0;
3074 zfix dx = zc::math::Cos(v)*px, dy = zc::math::Sin(v)*px;
3075 return movexy(dx, dy, special, kb);
3076 }
3077
3078 bool enemy::can_movexy(zfix dx, zfix dy, int32_t special, bool kb)
3079 {
3080 zfix tx = x, ty = y;
3081 bool ret = movexy(dx, dy, special, kb);
3082 x = tx;
3083 y = ty;
3084 return ret;
3085 }
3086 bool enemy::can_moveDir(int32_t dir, zfix px, int32_t special, bool kb)
3087 {
3088 zfix tx = x, ty = y;
3089 bool ret = moveDir(dir, px, special, kb);
3090 x = tx;
3091 y = ty;
3092 return ret;
3093 }
3094 bool enemy::can_moveAtAngle(zfix degrees, zfix px, int32_t special, bool kb)
3095 {
3096 zfix tx = x, ty = y;
3097 bool ret = moveAtAngle(degrees, px, special, kb);
3098 x = tx;
3099 y = ty;
3100 return ret;
3101 }
3102
3103 // Handle pitfalls
3104 52054 bool enemy::do_falling(int32_t index)
3105 {
3106
1/2
✓ Branch 0 taken 52054 times.
✗ Branch 1 not taken.
52054 if(fallclk > 0)
3107 {
3108 if(fallclk == PITFALL_FALL_FRAMES && fallCombo) sfx(combobuf[fallCombo].attribytes[0], pan(x.getInt()));
3109 if(!--fallclk)
3110 {
3111 if(immortal) //Keep alive forever
3112 ++fallclk; //force another frame of falling.... forever.
3113 else if(dying) //Give 1 frame for script revival
3114 {
3115 if(flags&guy_neverret)
3116 never_return(index);
3117
3118 if(leader)
3119 kill_em_all();
3120
3121 //leave_item(); //Don't drop items in pits!
3122 stop_bgsfx(index);
3123 return true;
3124 }
3125 else
3126 {
3127 try_death(true); //Force death
3128 ++fallclk; //force another frame of falling
3129 }
3130 }
3131
3132 wpndata& spr = wpnsbuf[QMisc.sprites[sprFALL]];
3133 cs = spr.csets & 0xF;
3134 int32_t fr = spr.frames ? spr.frames : 1;
3135 int32_t spd = spr.speed ? spr.speed : 1;
3136 int32_t animclk = (PITFALL_FALL_FRAMES-fallclk);
3137 tile = spr.tile + zc_min(animclk / spd, fr-1);
3138 }
3139 52054 return false;
3140 52054 }
3141
3142 // Handle drowning in water
3143 52054 bool enemy::do_drowning(int32_t index)
3144 {
3145
1/2
✓ Branch 0 taken 52054 times.
✗ Branch 1 not taken.
52054 if(drownclk > 0)
3146 {
3147 //if(drownclk == WATER_DROWN_FRAMES && drownCombo) sfx(combobuf[drownCombo].attribytes[0], pan(x.getInt()));
3148 //!TODO: Drown SFX
3149 if(!--drownclk)
3150 {
3151 if(immortal) //Keep alive forever
3152 ++drownclk; //force another frame of falling.... forever.
3153 else if(dying) //Give 1 frame for script revival
3154 {
3155 if(flags&guy_neverret)
3156 never_return(index);
3157
3158 if(leader)
3159 kill_em_all();
3160
3161 //leave_item(); //Don't drop items in pits!
3162 stop_bgsfx(index);
3163 return true;
3164 }
3165 else
3166 {
3167 try_death(true); //Force death
3168 ++drownclk; //force another frame of falling
3169 }
3170 }
3171
3172 if (drownCombo && combobuf[drownCombo].usrflags&cflag1)
3173 {
3174 wpndata &spr = wpnsbuf[QMisc.sprites[sprLAVADROWN]];
3175 cs = spr.csets & 0xF;
3176 int32_t fr = spr.frames ? spr.frames : 1;
3177 int32_t spd = spr.speed ? spr.speed : 1;
3178 int32_t animclk = (WATER_DROWN_FRAMES-drownclk);
3179 tile = spr.tile + zc_min((animclk % (spd*fr))/spd, fr-1);
3180 }
3181 else
3182 {
3183 wpndata &spr = wpnsbuf[QMisc.sprites[sprDROWN]];
3184 cs = spr.csets & 0xF;
3185 int32_t fr = spr.frames ? spr.frames : 1;
3186 int32_t spd = spr.speed ? spr.speed : 1;
3187 int32_t animclk = (WATER_DROWN_FRAMES-drownclk);
3188 tile = spr.tile + zc_min((animclk % (spd*fr))/spd, fr-1);
3189 }
3190 }
3191 52054 return false;
3192 52054 }
3193
3194 // Supplemental animation code that all derived classes should call
3195 // as a return value for animate().
3196 // Handles the death animation and returns true when enemy is finished.
3197 52923 bool enemy::Dead(int32_t index)
3198 {
3199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52923 times.
52923 if(immortal)
3200 {
3201 dying = false;
3202 return false;
3203 }
3204
2/2
✓ Branch 0 taken 918 times.
✓ Branch 1 taken 52005 times.
52923 if(dying)
3205 {
3206
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 918 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
918 if(deathexstate > -1 && deathexstate < 32)
3207 {
3208 setxmapflag(1<<deathexstate);
3209 deathexstate = -1;
3210 }
3211 918 --clk2;
3212
3213
2/4
✓ Branch 0 taken 918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
918 if((get_bit(quest_rules,qr_HARDCODED_ENEMY_ANIMS) && clk2==12)
3214
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 870 times.
918 && hp>-1000) // not killed by ringleader
3215 48 death_sfx();
3216
3217
2/2
✓ Branch 0 taken 870 times.
✓ Branch 1 taken 48 times.
918 if(clk2==0)
3218 {
3219
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 1 times.
48 if(flags&guy_neverret)
3220 1 never_return(index);
3221
3222
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if(leader)
3223 kill_em_all();
3224
3225 48 leave_item();
3226 48 }
3227
3228 918 stop_bgsfx(index);
3229 918 return (clk2==0);
3230 }
3231
3232 52005 return false;
3233 52923 }
3234
3235 // Basic animation code that all derived classes should call.
3236 // The one with an index is the one that is called by
3237 // the guys sprite list; index is the enemy's index in the list.
3238 54704 bool enemy::animate(int32_t index)
3239 {
3240
2/2
✓ Branch 0 taken 3397 times.
✓ Branch 1 taken 51307 times.
54704 if(sclk <= 0) hitdir = -1;
3241
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54704 times.
54704 if(switch_hooked)
3242 {
3243 if(get_bit(quest_rules, qr_SWITCHOBJ_RUN_SCRIPT))
3244 {
3245 //Run its script
3246 if (run_script(MODE_NORMAL)==RUNSCRIPT_SELFDELETE)
3247 {
3248 return 0; //Avoid NULLPO if this object deleted itself
3249 }
3250 }
3251 return false;
3252 }
3253
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54704 times.
54704 if(do_falling(index)) return true;
3254
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54704 times.
54704 else if(fallclk)
3255 {
3256 //clks
3257 if(hclk>0)
3258 --hclk;
3259 if(stunclk>0)
3260 --stunclk;
3261 if ( frozenclock > 0 )
3262 --frozenclock;
3263 if(hashero)
3264 {
3265 Hero.setX(x);
3266 Hero.setY(y);
3267 Hero.fallCombo = fallCombo;
3268 Hero.fallclk = fallclk;
3269 hashero = false; //Let Hero go if falling
3270 }
3271 run_script(MODE_NORMAL);
3272 return false;
3273 }
3274
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54704 times.
54704 if(do_drowning(index)) return true;
3275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54704 times.
54704 else if(drownclk)
3276 {
3277 //clks
3278 if(hclk>0)
3279 --hclk;
3280 if(stunclk>0)
3281 --stunclk;
3282 if ( frozenclock > 0 )
3283 --frozenclock;
3284 if(hashero)
3285 {
3286 Hero.setX(x);
3287 Hero.setY(y);
3288 Hero.drownclk = drownclk;
3289 hashero = false; //Let Hero go if falling
3290 }
3291 run_script(MODE_NORMAL);
3292 return false;
3293 }
3294 54704 int32_t nx = real_x(x);
3295 54704 int32_t ny = real_y(y);
3296
3297
4/4
✓ Branch 0 taken 38227 times.
✓ Branch 1 taken 16477 times.
✓ Branch 2 taken 5757 times.
✓ Branch 3 taken 43984 times.
54704 if(ox!=nx || oy!=ny)
3298 {
3299 22234 posframe=(posframe+1)%(get_bit(quest_rules,qr_NEWENEMYTILES)?4:2);
3300 22234 }
3301
3302 66218 ox = nx;
3303 66218 oy = ny;
3304
3305 // Maybe they fell off the bottom in sideview, or were moved by a script.
3306
3307 //Check offscreen settings. I wrote it this way for clarity and to simplify testing. -Z
3308
2/2
✓ Branch 0 taken 14164 times.
✓ Branch 1 taken 52054 times.
66218 if ( immortal )
3309 {
3310 //skip, as it can go out of bounds, from immortality
3311 14164 }
3312
2/6
✓ Branch 0 taken 52054 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 52054 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
52054 else if ( (moveflags & FLAG_IGNORE_SCREENEDGE) || (( (get_bit(quest_rules, qr_OUTOFBOUNDSENEMIES)) != (editorflags&ENEMY_FLAG11) ) && !NEWOUTOFBOUNDS(x,y,z+fakez)) )
3313 {
3314 //skip, it can go out of bounds, from a quest rule, or from the enemy editor (but not both!)
3315 }
3316
6/10
✓ Branch 0 taken 45324 times.
✓ Branch 1 taken 6730 times.
✓ Branch 2 taken 52054 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 52054 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 52054 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 52054 times.
52054 else if ( (OUTOFBOUNDS) )
3317 {
3318 hp=-1000; //kill it, as it is not immortal, and no quest bit or rule is enabled
3319 }
3320 //fall down
3321
6/6
✓ Branch 0 taken 11059 times.
✓ Branch 1 taken 55159 times.
✓ Branch 2 taken 40995 times.
✓ Branch 3 taken 25223 times.
✓ Branch 4 taken 2506 times.
✓ Branch 5 taken 38489 times.
66218 if((enemycanfall(id) || (moveflags & FLAG_OBEYS_GRAV) )&& fading != fade_flicker && clk>=0)
3322 {
3323
2/2
✓ Branch 0 taken 6430 times.
✓ Branch 1 taken 32059 times.
38489 if(isSideViewGravity())
3324 {
3325
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6430 times.
6430 if(get_bit(quest_rules,qr_OLD_SIDEVIEW_LANDING_CODE))
3326 {
3327 if(!isOnSideviewPlatform())
3328 {
3329 bool willHitSVPlatform = false;
3330 int32_t usewid = (SIZEflags&guyflagOVERRIDE_HIT_WIDTH)?hxsz:16;
3331 int32_t usehei = (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT)?hysz:16;
3332 for(int32_t nx = x+4; nx < x+usewid; nx+=16)
3333 {
3334 if(fall > 0 && !IGNORE_SIDEVIEW_PLATFORMS && checkSVLadderPlatform(x+4,y+(fall/100)+usehei-1) && (((int32_t(y)+(int32_t(fall)/100)+usehei-1)&0xF0)!=((int32_t(y)+usehei-1)&0xF0)))
3335 {
3336 willHitSVPlatform = true;
3337 break;
3338 }
3339 }
3340 if(willHitSVPlatform)
3341 {
3342 y+=fall/100;
3343 //y-=int32_t(y)%16; //Fix to top of SV Ladder
3344 do_fix(y, 16); //Fix to top of SV Ladder
3345 fall = 0;
3346 }
3347 else
3348 {
3349 y+=fall/100;
3350 if(fall <= (int32_t)zinit.terminalv)
3351 fall += (zinit.gravity2/100);
3352 }
3353 }
3354 else
3355 {
3356 if(fall!=0) // Only fix pos once
3357 {
3358 //y-=(int32_t)y%8; // Fix position
3359 do_fix(y, 8); //Fix position
3360 }
3361
3362 fall = 0;
3363 }
3364 }
3365 else
3366 {
3367
2/2
✓ Branch 0 taken 5858 times.
✓ Branch 1 taken 572 times.
6430 if(isOnSideviewPlatform())
3368 5858 fall = 0;
3369 else
3370 {
3371 572 zfix fall_amnt = fall/100;
3372 572 bool hit = false;
3373
2/2
✓ Branch 0 taken 543 times.
✓ Branch 1 taken 706 times.
1249 while(fall_amnt >= 1)
3374 {
3375 706 --fall_amnt;
3376 706 ++y;
3377
2/2
✓ Branch 0 taken 677 times.
✓ Branch 1 taken 29 times.
706 if(isOnSideviewPlatform())
3378 {
3379 29 y = y.getInt();
3380 29 fall_amnt = 0;
3381 29 hit = true;
3382 29 break;
3383 }
3384 }
3385
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 512 times.
572 if(fall_amnt > 0)
3386 512 y += fall_amnt;
3387
1/2
✓ Branch 0 taken 572 times.
✗ Branch 1 not taken.
572 if(fall_amnt < 0)
3388 {
3389 if(!movexy(0,fall_amnt,spw_none))
3390 hit = true;
3391 }
3392
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 543 times.
572 if(hit)
3393 29 fall = 0;
3394
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 430 times.
543 else if(fall <= (int32_t)zinit.terminalv)
3395 430 fall += (zinit.gravity2/100);
3396 }
3397 }
3398 6430 }
3399 else
3400 {
3401
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32059 times.
32059 if (!(moveflags & FLAG_NO_FAKE_Z))
3402 {
3403
2/2
✓ Branch 0 taken 24053 times.
✓ Branch 1 taken 8006 times.
32059 if(fakefall!=0)
3404 8006 fakez-=(fakefall/100);
3405
3406
2/2
✓ Branch 0 taken 8006 times.
✓ Branch 1 taken 24053 times.
32059 if(fakez<0)
3407 8006 fakez = fakefall = 0;
3408
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24053 times.
24053 else if(fakefall <= (int32_t)zinit.terminalv)
3409 24053 fakefall += (zinit.gravity2/100);
3410
3411
5/6
✓ Branch 0 taken 32059 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24053 times.
✓ Branch 3 taken 8006 times.
✓ Branch 4 taken 8034 times.
✓ Branch 5 taken 16019 times.
32059 if (fakez<=0 && fakefall > 0 && !get_bit(quest_rules, qr_FLUCTUATING_ENEMY_JUMP)) fakefall = 0;
3412 32059 }
3413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32059 times.
32059 if (!(moveflags & FLAG_NO_REAL_Z))
3414 {
3415
2/2
✓ Branch 0 taken 24053 times.
✓ Branch 1 taken 8006 times.
32059 if(fall!=0)
3416 8006 z-=(fall/100);
3417
3418
2/2
✓ Branch 0 taken 8006 times.
✓ Branch 1 taken 24053 times.
32059 if(z<0)
3419 8006 z = fall = 0;
3420
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24053 times.
24053 else if(fall <= (int32_t)zinit.terminalv)
3421 24053 fall += (zinit.gravity2/100);
3422
3423
5/6
✓ Branch 0 taken 32059 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24053 times.
✓ Branch 3 taken 8006 times.
✓ Branch 4 taken 8034 times.
✓ Branch 5 taken 16019 times.
32059 if (z<=0 && fall > 0 && !get_bit(quest_rules, qr_FLUCTUATING_ENEMY_JUMP)) fall = 0;
3424 32059 }
3425
3426 }
3427 38489 }
3428
4/4
✓ Branch 0 taken 45324 times.
✓ Branch 1 taken 20894 times.
✓ Branch 2 taken 42510 times.
✓ Branch 3 taken 87834 times.
66218 if(!isSideViewGravity() && (moveflags & FLAG_CAN_PITFALL))
3429 {
3430
7/10
✓ Branch 0 taken 29568 times.
✓ Branch 1 taken 58266 times.
✓ Branch 2 taken 29568 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 29568 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 29568 times.
✓ Branch 8 taken 29568 times.
✓ Branch 9 taken 29568 times.
87834 if(can_pitfall() && ((z <= 0 && fakez <= 0 && !isflier(id)) || (isflier(id) && (stunclk))) && !superman)
3431 {
3432 29568 fallCombo = check_pits();
3433 29568 }
3434 146970 }
3435
3/4
✓ Branch 0 taken 45324 times.
✓ Branch 1 taken 6730 times.
✓ Branch 2 taken 45324 times.
✗ Branch 3 not taken.
93842 if(!isSideViewGravity() && (moveflags & FLAG_CAN_WATERDROWN))
3436 {
3437 if(can_pitfall() && ((z <= 0 && fakez <= 0 && !isflier(id)) || (isflier(id) && (stunclk))) && !superman)
3438 {
3439 drownCombo = check_water();
3440 }
3441 }
3442
3443 52054 runKnockback(); //scripted knockback handling
3444
3445 // clk is incremented here
3446
2/2
✓ Branch 0 taken 49003 times.
✓ Branch 1 taken 3051 times.
52054 if(++clk >= frate)
3447 3051 clk=0;
3448
3449 // hit and death handling
3450
2/2
✓ Branch 0 taken 51114 times.
✓ Branch 1 taken 940 times.
52054 if(hclk>0)
3451 940 --hclk;
3452
3453
1/2
✓ Branch 0 taken 52054 times.
✗ Branch 1 not taken.
52054 if(stunclk>0)
3454 --stunclk;
3455
1/2
✓ Branch 0 taken 52054 times.
✗ Branch 1 not taken.
52054 if ( frozenclock > 0 )
3456 --frozenclock;
3457
3458
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 52054 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
52054 if(ceiling && z <= 0 && fakez <= 0)
3459 ceiling = false;
3460
3461 52054 try_death();
3462
3463 52054 scored=false;
3464
3465 52054 ++c_clk;
3466
3467 //Run its script
3468
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52054 times.
52054 if (run_script(MODE_NORMAL)==RUNSCRIPT_SELFDELETE)
3469 {
3470 return 0; //Avoid NULLPO if this object deleted itself
3471 }
3472
3473 // returns true when enemy is defeated
3474 52054 return Dead(index);
3475 52054 }
3476
3477 52875 bool enemy::setSolid(bool set)
3478 {
3479
1/2
✓ Branch 0 taken 52875 times.
✗ Branch 1 not taken.
52875 bool actual = set && !isSubmerged();
3480 52875 bool ret = solid_object::setSolid(actual);
3481 52875 solid = set;
3482 52875 return ret;
3483 }
3484 void enemy::doContactDamage(int32_t hdir)
3485 {
3486 Hero.hithero(guys.find(this), hdir);
3487 }
3488
3489 21877 void enemy::solid_push(solid_object *obj)
3490 {
3491
1/2
✓ Branch 0 taken 21877 times.
✗ Branch 1 not taken.
21877 if(obj == this) return; //can't push self
3492
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21877 times.
21877 if(moveflags&FLAG_NOT_PUSHABLE) return; //not pushable
3493 21877 zfix dx, dy;
3494 21877 int32_t hdir = -1;
3495 21877 solid_push_int(obj,dx,dy,hdir);
3496
3497
4/4
✓ Branch 0 taken 21417 times.
✓ Branch 1 taken 460 times.
✓ Branch 2 taken 21009 times.
✓ Branch 3 taken 408 times.
21877 if(!dx && !dy) return;
3498
3499 868 bool t = obj->getTempNonsolid();
3500 868 obj->setTempNonsolid(true);
3501
3502 868 int32_t ydir = dy > 0 ? down : up;
3503 868 int32_t xdir = dx > 0 ? right : left;
3504
3505 868 auto special = isflier(id) ? spw_floater : spw_none;
3506
2/2
✓ Branch 0 taken 807 times.
✓ Branch 1 taken 61 times.
868 if(!movexy(dx,dy,special,true,true))
3507 {
3508 //Crushed?
3509 61 }
3510
3511 868 obj->setTempNonsolid(t);
3512 21877 }
3513 21877 bool enemy::is_unpushable() const
3514 {
3515 21877 return isSubmerged();
3516 }
3517 21877 bool enemy::sideview_mode() const
3518 {
3519
3/4
✓ Branch 0 taken 6730 times.
✓ Branch 1 taken 15147 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6730 times.
21877 return isSideViewGravity() && (moveflags&FLAG_OBEYS_GRAV) && !(moveflags&FLAG_NOT_PUSHABLE);
3520 }
3521
3522 bool enemy::m_walkflag_old(int32_t dx,int32_t dy,int32_t special, int32_t x, int32_t y)
3523 {
3524 int32_t yg = (special==spw_floater)?8:0;
3525 int32_t nb = get_bit(quest_rules, qr_NOBORDER) ? 16 : 0;
3526
3527 if(dx<16-nb || dy<zc_max(16-yg-nb,0) || dx>=240+nb || dy>=160+nb)
3528 return true;
3529
3530 bool isInDungeon = isdungeon();
3531 if(isInDungeon || special==spw_wizzrobe)
3532 {
3533 if((x>=32 && dy<32-yg) || (y>-1000 && y<=144 && dy>=144))
3534 return true;
3535
3536 if((x>=32 && dx<32) || (x>-1000 && x<224 && dx>=224))
3537 if(special!=spw_door) // walk in door way
3538 return true;
3539 }
3540
3541 if(!(moveflags & FLAG_CAN_PITWALK) && !(moveflags & FLAG_CAN_PITFALL)) //Don't walk into pits (knockback doesn't call this func)
3542 {
3543 if(ispitfall(dx,dy) || ispitfall(dx+8,dy)
3544 || ispitfall(dx,dy+8) || ispitfall(dx+8,dy+8))
3545 return true;
3546 }
3547
3548 switch(special)
3549 {
3550 case spw_clipbottomright:
3551 if(dy>=128 || dx>=208) return true;
3552 break;
3553 case spw_clipright:
3554 break; //if(x>=208) return true; break;
3555
3556 case spw_wizzrobe: // fall through
3557 case spw_floater: // Special case for fliers and wizzrobes - hack!
3558 {
3559 if(isInDungeon)
3560 {
3561 if(dy < 32-yg || dy >= 144) return true;
3562 if(dx < 32 || dx >= 224) return true;
3563 }
3564 return false;
3565 }
3566 }
3567
3568 dx&=(special==spw_halfstep)?(~7):(~15);
3569 dy&=(special==spw_halfstep || isSideViewGravity())?(~7):(~15);
3570
3571 if(special==spw_water)
3572 return (water_walkflag(dx,dy+8,1) || water_walkflag(dx+8,dy+8,1));
3573
3574 return _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
3575 groundblocked(dx,dy+8) || groundblocked(dx+8,dy+8);
3576 }
3577
3578 bool enemy::m_walkflag_simple(int32_t dx,int32_t dy)
3579 {
3580 bool kb = false;
3581 int32_t nb = get_bit(quest_rules, qr_NOBORDER) ? 16 : 0;
3582
3583 if(dx<16-nb || dy<zc_max(16-nb,0) || dx>=240+nb || dy>=160+nb)
3584 return true;
3585
3586 if(isdungeon())
3587 {
3588 if((dy<32) || (dy>=144))
3589 return true;
3590
3591 if((dx<32) || (dx>=224))
3592 return true;
3593 }
3594
3595 if(!(moveflags & FLAG_CAN_PITWALK) && (!(moveflags & FLAG_CAN_PITFALL))) //Don't walk into pits, unless being knocked back
3596 {
3597 if(ispitfall(dx,dy) || ispitfall(dx+8,dy)
3598 || ispitfall(dx,dy+8) || ispitfall(dx+8,dy+8))
3599 return true;
3600 }
3601
3602 if(get_bit(quest_rules,qr_ENEMY_BROKEN_TOP_HALF_SOLIDITY))
3603 {
3604 return _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
3605 groundblocked(dx,dy+8,kb) || groundblocked(dx+8,dy+8,kb);
3606 }
3607 else
3608 {
3609 return _walkflag(dx,dy,1) || _walkflag(dx+8,dy,1) ||
3610 _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
3611 groundblocked(dx,dy,kb) || groundblocked(dx+8,dy,kb) ||
3612 groundblocked(dx,dy+8,kb) || groundblocked(dx+8,dy+8,kb);
3613 }
3614 }
3615
3616 18149 bool enemy::m_walkflag(int32_t dx,int32_t dy,int32_t special, int32_t dir, int32_t input_x, int32_t input_y, bool kb)
3617 {
3618
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18149 times.
18149 if(moveflags & FLAG_USE_NEW_MOVEMENT)
3619 return scr_walkflag(dx,dy,special,dir,input_x,input_y,kb);
3620 18149 int32_t yg = (special==spw_floater)?8:0;
3621 18149 int32_t nb = get_bit(quest_rules, qr_NOBORDER) ? 16 : 0;
3622
2/2
✓ Branch 0 taken 2671 times.
✓ Branch 1 taken 15478 times.
18149 switch(dir)
3623 {
3624 case l_down:
3625 case r_down:
3626 case down:
3627 case 11: //r_down
3628 case 12: //down
3629 case 13: //l_down
3630 {
3631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2671 times.
2671 if ( ((unsigned)(id&0xFFF)) < MAXGUYS )
3632 {
3633
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2671 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2671 if ( SIZEflags&guyflagOVERRIDE_HIT_HEIGHT && !isflier(id) )
3634 {
3635 //Small enemies are treated as 16x16, for the purposes of m_walkflag!
3636 dy += zc_max(hysz-16,0);
3637 }
3638 2671 }
3639 2671 break;
3640 }
3641 }
3642
2/2
✓ Branch 0 taken 2310 times.
✓ Branch 1 taken 15839 times.
18149 switch(dir)
3643 {
3644 case r_up:
3645 case r_down:
3646 case right:
3647 case 9: //r_up
3648 case 10: //right
3649 case 11: //r_down
3650 {
3651
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2310 times.
2310 if ( ((unsigned)(id&0xFFF)) < MAXGUYS )
3652 {
3653
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2310 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2310 if ( SIZEflags&guyflagOVERRIDE_HIT_WIDTH && !isflier(id) )
3654 {
3655 //Small enemies are treated as 16x16, for the purposes of m_walkflag!
3656 dx += zc_max(hxsz-16,0);
3657 }
3658 2310 }
3659 2310 break;
3660 }
3661 }
3662 //Z_eventlog("Checking x,y %d,%d\n",dx,dy);
3663
3664
10/10
✓ Branch 0 taken 12812 times.
✓ Branch 1 taken 5337 times.
✓ Branch 2 taken 1508 times.
✓ Branch 3 taken 3829 times.
✓ Branch 4 taken 5313 times.
✓ Branch 5 taken 24 times.
✓ Branch 6 taken 5244 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 13030 times.
✓ Branch 9 taken 18274 times.
18149 if(dx<16-nb || dy<zc_max(16-yg-nb,0) || dx>=240+nb || dy>=160+nb)
3665 25935 return true;
3666
3667 18274 bool isInDungeon = isdungeon();
3668
3/4
✓ Branch 0 taken 1735 times.
✓ Branch 1 taken 16539 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1735 times.
18274 if(isInDungeon || special==spw_wizzrobe)
3669 {
3670
7/8
✓ Branch 0 taken 3397 times.
✓ Branch 1 taken 13142 times.
✓ Branch 2 taken 3285 times.
✓ Branch 3 taken 112 times.
✓ Branch 4 taken 3357 times.
✓ Branch 5 taken 9897 times.
✓ Branch 6 taken 3357 times.
✗ Branch 7 not taken.
16539 if((input_x>=32 && dy<32-yg) || (input_y>-1000 && input_y<=144 && dy>=144))
3671 6642 return true;
3672
3673
7/8
✓ Branch 0 taken 3325 times.
✓ Branch 1 taken 6572 times.
✓ Branch 2 taken 3281 times.
✓ Branch 3 taken 44 times.
✓ Branch 4 taken 3326 times.
✓ Branch 5 taken 3290 times.
✓ Branch 6 taken 3326 times.
✗ Branch 7 not taken.
9897 if((input_x>=32 && dx<32) || (input_x>-1000 && input_x<224 && dx>=224))
3674
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
6607 if(special!=spw_door) // walk in door way
3675 45 return true;
3676 3290 }
3677
3678
5/6
✓ Branch 0 taken 2118 times.
✓ Branch 1 taken 2907 times.
✓ Branch 2 taken 2118 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 152 times.
✓ Branch 5 taken 1966 times.
5025 if(!(moveflags & FLAG_CAN_PITWALK) && (!(moveflags & FLAG_CAN_PITFALL) || !kb)) //Don't walk into pits, unless being knocked back
3679 {
3680
2/4
✓ Branch 0 taken 1966 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1966 times.
3932 if(ispitfall(dx,dy) || ispitfall(dx+8,dy)
3681
2/4
✓ Branch 0 taken 1966 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1966 times.
✗ Branch 3 not taken.
1966 || ispitfall(dx,dy+8) || ispitfall(dx+8,dy+8))
3682 return true;
3683 1966 }
3684
3685
2/4
✓ Branch 0 taken 2890 times.
✓ Branch 1 taken 2135 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5025 switch(special)
3686 {
3687 case spw_clipbottomright:
3688 if(dy>=128 || dx>=208) return true;
3689 break;
3690 case spw_clipright:
3691 break; //if(input_x>=208) return true; break;
3692
3693 case spw_wizzrobe: // fall through
3694 case spw_floater: // Special case for fliers and wizzrobes - hack!
3695 {
3696
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2890 times.
2890 if(isInDungeon)
3697 {
3698
2/4
✓ Branch 0 taken 2890 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2890 times.
2890 if(dy < 32-yg || dy >= 144) return true;
3699
3/4
✓ Branch 0 taken 2883 times.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2883 times.
2890 if(dx < 32 || dx >= 224) return true;
3700 2883 }
3701 2883 return false;
3702 }
3703 }
3704
3705 2135 dx&=(special==spw_halfstep)?(~7):(~15);
3706
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2129 times.
2135 dy&=(special==spw_halfstep || isSideViewGravity())?(~7):(~15);
3707
3708
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2135 times.
2135 if(special==spw_water)
3709 return (water_walkflag(dx,dy+8,1) || water_walkflag(dx+8,dy+8,1));
3710
3711
2/2
✓ Branch 0 taken 805 times.
✓ Branch 1 taken 1330 times.
2135 if(get_bit(quest_rules,qr_ENEMY_BROKEN_TOP_HALF_SOLIDITY))
3712 {
3713
4/4
✓ Branch 0 taken 711 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 707 times.
✓ Branch 3 taken 4 times.
1512 return _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
3714
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 707 times.
707 groundblocked(dx,dy+8,kb) || groundblocked(dx+8,dy+8,kb);
3715 }
3716 else
3717 {
3718
4/4
✓ Branch 0 taken 1111 times.
✓ Branch 1 taken 219 times.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 24 times.
2417 return _walkflag(dx,dy,1) || _walkflag(dx+8,dy,1) ||
3719
4/4
✓ Branch 0 taken 1023 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 1018 times.
✓ Branch 3 taken 5 times.
1087 _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
3720
3/4
✓ Branch 0 taken 942 times.
✓ Branch 1 taken 76 times.
✓ Branch 2 taken 942 times.
✗ Branch 3 not taken.
1018 groundblocked(dx,dy,kb) || groundblocked(dx+8,dy,kb) ||
3721
1/2
✓ Branch 0 taken 942 times.
✗ Branch 1 not taken.
942 groundblocked(dx,dy+8,kb) || groundblocked(dx+8,dy+8,kb);
3722 }
3723 5453 }
3724
3725 11412 bool enemy::isOnSideviewPlatform()
3726 {
3727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11412 times.
11412 int32_t usewid = (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) ? hxsz : 16;
3728
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11412 times.
11412 int32_t usehei = (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) ? hysz : 16;
3729
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 11412 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
11412 if(y + usehei >= 176 && currscr>=0x70 && !(tmpscr->flags2&wfDOWN)) return true; //Bottom of the map
3730
2/2
✓ Branch 0 taken 606 times.
✓ Branch 1 taken 10806 times.
11412 if(check_slope(x, y+1, usewid, usehei)) return true;
3731
2/2
✓ Branch 0 taken 10806 times.
✓ Branch 1 taken 1693 times.
12499 for(int32_t nx = x + 4; nx <= x + usewid - 4; nx+=16)
3732 {
3733
2/2
✓ Branch 0 taken 1693 times.
✓ Branch 1 taken 9113 times.
10806 if(_walkflag(nx,y+usehei,1)) return true;
3734
3/4
✓ Branch 0 taken 1693 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1494 times.
✓ Branch 3 taken 199 times.
1693 if(IGNORE_SIDEVIEW_PLATFORMS || ((int32_t(y)+usehei)%16)!=0) continue;
3735
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
199 if(checkSVLadderPlatform(nx,y+usehei)) return true;
3736 199 }
3737 1693 return false;
3738 11412 }
3739
3740 // Stops playing the given sound only if there are no enemies left to play it
3741 918 void enemy::stop_bgsfx(int32_t index)
3742 {
3743
2/2
✓ Branch 0 taken 899 times.
✓ Branch 1 taken 19 times.
918 if(bgsfx<=0)
3744 899 return;
3745
3746 // Look for other enemies with the same bgsfx
3747
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 19 times.
38 for(int32_t i=0; i<guys.Count(); i++)
3748 {
3749
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
19 if(i!=index && ((enemy*)guys.spr(i))->bgsfx==bgsfx)
3750 return;
3751 19 }
3752
3753 19 stop_sfx(bgsfx);
3754 918 }
3755
3756
3757 // to allow for different sfx on defeating enemy
3758 48 void enemy::death_sfx()
3759 {
3760
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if(deadsfx > 0) sfx(deadsfx,pan(int32_t(x)));
3761 48 }
3762
3763 void enemy::move(zfix dx,zfix dy)
3764 {
3765 /*if(FFCore.getQuestHeaderInfo(vZelda) >= 0x255 && FFCore.getQuestHeaderInfo(vBuild) >= 50 )
3766 {
3767 switch(family)
3768 {
3769 case eeFIRE:
3770 case eeOTHER:
3771 return;
3772 default: break;
3773 }
3774 if(family >= eeSCRIPT01 && family <= eeFFRIENDLY10 ) return;
3775 }
3776 */
3777 if(!watch && (!(isSideViewGravity()) || isOnSideviewPlatform() || !(moveflags & FLAG_OBEYS_GRAV) || !enemycanfall(id)))
3778 {
3779 x+=dx;
3780 y+=dy;
3781 }
3782 }
3783
3784 26933 void enemy::move(zfix s)
3785 {
3786 /*if(FFCore.getQuestHeaderInfo(vZelda) >= 0x255 && FFCore.getQuestHeaderInfo(vBuild) >= 50 )
3787 {
3788 switch(family)
3789 {
3790 case eeFIRE:
3791 case eeOTHER:
3792 return;
3793 default: break;
3794 }
3795 if(family >= eeSCRIPT01 && family <= eeFFRIENDLY10 ) return;
3796 }*/
3797
7/10
✓ Branch 0 taken 26933 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4276 times.
✓ Branch 3 taken 22657 times.
✓ Branch 4 taken 444 times.
✓ Branch 5 taken 3832 times.
✓ Branch 6 taken 444 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 444 times.
✗ Branch 9 not taken.
26933 if(!watch && (!(isSideViewGravity()) || isOnSideviewPlatform() || !enemycanfall(id) || !(moveflags & FLAG_OBEYS_GRAV)))
3798 {
3799 26489 sprite::move(s);
3800 26489 }
3801 26933 }
3802
3803 48 void enemy::leave_item()
3804 {
3805 48 int32_t drop_item = select_dropitem(item_set, x, y);
3806 48 int32_t thedropset = item_set;
3807
3808 48 std::vector<int32_t> &ev = FFCore.eventData;
3809 48 ev.clear();
3810 48 ev.push_back(getUID());
3811 48 ev.push_back(drop_item*10000);
3812 48 ev.push_back(thedropset*10000);
3813
3814 48 throwGenScriptEvent(GENSCR_EVENT_ENEMY_DROP_ITEM_1);
3815 48 drop_item = vbound(ev[1] / 10000,-2,255);
3816 48 thedropset = ev[2] / 10000;
3817 48 ev.clear();
3818
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if(drop_item == -2)
3819 {
3820 drop_item = select_dropitem(thedropset,x,y);
3821 }
3822
3823
3/6
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
48 if(drop_item>=0&&((itemsbuf[drop_item].family!=itype_fairy)||!m_walkflag(x,y,0,dir)))
3824 {
3825 item* itm;
3826
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (get_bit(quest_rules, qr_ENEMY_DROPS_USE_HITOFFSETS))
3827 {
3828 itm = (new item(x+hxofs+(hxsz/2)-8,y+hyofs+(hysz/2)-8,(zfix)0,drop_item,ipBIGRANGE+ipTIMER,0));
3829 }
3830 else
3831 {
3832
1/14
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
15 if(extend >= 3) itm = (new item(x+(txsz-1)*8,y+(tysz-1)*8,(zfix)0,drop_item,ipBIGRANGE+ipTIMER,0));
3833
4/8
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15 times.
✗ Branch 7 not taken.
15 else itm = (new item(x,y,(zfix)0,drop_item,ipBIGRANGE+ipTIMER,0));
3834 }
3835 15 itm->from_dropset = thedropset;
3836 15 items.add(itm);
3837
3838 15 ev.push_back(getUID());
3839 15 ev.push_back(itm->getUID());
3840
3841 15 throwGenScriptEvent(GENSCR_EVENT_ENEMY_DROP_ITEM_2);
3842 15 ev.clear();
3843 15 }
3844 48 }
3845
3846 // auomatically kill off enemy (for rooms with ringleaders)
3847 void enemy::kickbucket()
3848 {
3849 if(!superman)
3850 hp=-1000; // don't call death_sfx()
3851 }
3852
3853 21877 bool enemy::isSubmerged() const
3854 {
3855 21877 return submerged;
3856 //!TODO SOLIDPUSH more things like teleporting wizzrobes
3857 }
3858
3859 void enemy::FireBreath(bool seekhero)
3860 {
3861 if(wpn==wNone)
3862 return;
3863
3864 if(wpn==ewFireTrail)
3865 {
3866 dmisc1 = e1tEACHTILE;
3867 FireWeapon();
3868 return;
3869 }
3870
3871 float fire_angle=0.0;
3872 int32_t wx=0, wy=0, wdir=dir;
3873
3874 if(!seekhero)
3875 {
3876 switch(dir)
3877 {
3878 case down:
3879 fire_angle=PI*(int64_t(zc_oldrand()%20)+10)/40;
3880 wx=x;
3881 wy=y+8;
3882 break;
3883
3884 case -1:
3885 case up:
3886 fire_angle=PI*(int64_t(zc_oldrand()%20)+50)/40;
3887 wx=x;
3888 wy=y-8;
3889 break;
3890
3891 case left:
3892 fire_angle=PI*(int64_t(zc_oldrand()%20)+30)/40;
3893 wx=x-8;
3894 wy=y;
3895 break;
3896
3897 case right:
3898 fire_angle=PI*(int64_t(zc_oldrand()%20)+70)/40;
3899 wx=x+8;
3900 wy=y;
3901 break;
3902 }
3903
3904 if(wpn==ewFlame || wpn==ewFlame2)
3905 {
3906 if(fire_angle==-PI || fire_angle==PI) wdir=left;
3907 else if(fire_angle==-PI/2) wdir=up;
3908 else if(fire_angle==PI/2) wdir=down;
3909 else if(fire_angle==0) wdir=right;
3910 else if(fire_angle<-PI/2) wdir=l_up;
3911 else if(fire_angle<0) wdir=r_up;
3912 else if(fire_angle<(PI/2)) wdir=r_down;
3913 else if(fire_angle<PI) wdir=l_down;
3914 }
3915 }
3916 else
3917 {
3918 wx = x;
3919 wy = y;
3920 }
3921
3922 addEwpn(wx,wy,z,wpn,2,wdp,seekhero ? 0xFF : wdir, getUID(), 0, fakez);
3923 sfx(wpnsfx(wpn),pan(int32_t(x)));
3924
3925 int32_t i=Ewpns.Count()-1;
3926 weapon *ew = (weapon*)(Ewpns.spr(i));
3927 ew->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
3928
3929 if(!seekhero && (zc_oldrand()&4))
3930 {
3931 ew->angular=true;
3932 ew->angle=fire_angle;
3933 }
3934
3935 if(wpn==ewFlame && wpnsbuf[ewFLAME].frames>1)
3936 {
3937 ew->aframe=zc_oldrand()%wpnsbuf[ewFLAME].frames;
3938 if ( ew->do_animation ) ew->tile+=ew->aframe;
3939 }
3940
3941 for(int32_t j=Ewpns.Count()-1; j>0; j--)
3942 {
3943 Ewpns.swap(j,j-1);
3944 }
3945 }
3946
3947 20 void enemy::FireWeapon()
3948 {
3949 /*
3950 * Type:
3951 * 0x01: Boss fireball
3952 * 0x02: Seeks Hero
3953 * 0x04: Fast projectile
3954 * 0x00-0x30: If 0x02, slants toward (type>>3)-1
3955 */
3956
3957
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (wpn < 1) return;
3958
1/10
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
20 if(wpn<wEnemyWeapons && dmisc1!=9 && dmisc1!=10 && (wpn < wScript1 && wpn > wScript10) ) // Summoning doesn't require weapons
3959 return;
3960
3961
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
20 if(wpn==ewFireTrail && dmisc1>=e1t3SHOTS && dmisc1<=e1t8SHOTS)
3962 dmisc1 = e1tEACHTILE;
3963
3964 20 int32_t xoff = 0;
3965 20 int32_t yoff = 0;
3966
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if ( SIZEflags&guyflagOVERRIDE_HIT_WIDTH )
3967 {
3968 xoff += (hxsz/2)-8;
3969 //Z_scripterrlog("width flag enabled. xoff = %d\n", xoff);
3970 }
3971
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if ( SIZEflags&guyflagOVERRIDE_HIT_HEIGHT )
3972 {
3973 yoff += (hysz/2)-8;
3974 //Z_scripterrlog("width flag enabled. yoff = %d\n", yoff);
3975 }
3976
3977
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
20 switch(dmisc1)
3978 {
3979 case e1t5SHOTS: //BS-Aquamentus
3980 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(((dir^left)+5)<<3),wdp,dir,-1, getUID(),false));
3981 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
3982 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(((dir^right)+5)<<3),wdp,dir,-1, getUID(),false));
3983 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
3984
3985 [[fallthrough]];
3986 case e1t3SHOTSFAST:
3987 case e1t3SHOTS: //Aquamentus
3988 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(((dir^left)+1)<<3)+(dmisc1==e1t3SHOTSFAST ? 4:0),wdp,dir,-1, getUID(),false));
3989 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
3990 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(((dir^right)+1)<<3)+(dmisc1==e1t3SHOTSFAST ? 4:0),wdp,dir,-1, getUID(),false));
3991 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
3992
3993 [[fallthrough]];
3994 default:
3995
11/20
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 20 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 20 times.
✓ Branch 12 taken 20 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 19 times.
✓ Branch 16 taken 20 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 20 times.
✗ Branch 19 not taken.
20 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(dmisc1==e1t3SHOTSFAST || dmisc1==e1tFAST ? 4:0),wdp,wpn==ewFireball2 || wpn==ewFireball ? 0:dir,-1, getUID(),false));
3996 20 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
3997 20 sfx(wpnsfx(wpn),pan(int32_t(x)));
3998 20 break;
3999
4000 case e1tSLANT:
4001 {
4002 int32_t slant = 0;
4003
4004 if(((Hero.x-x) < -8 && dir==up) || ((Hero.x-x) > 8 && dir==down) || ((Hero.y-y) < -8 && dir==left) || ((Hero.y-y) > 8 && dir==right))
4005 slant = left;
4006 else if(((Hero.x-x) > 8 && dir==up) || ((Hero.x-x) < -8 && dir==down) || ((Hero.y-y) > 8 && dir==left) || ((Hero.y-y) < -8 && dir==right))
4007 slant = right;
4008
4009 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(((dir^slant)+1)<<3),wdp,wpn==ewFireball2 || wpn==ewFireball ? 0:dir,-1, getUID(),false));
4010 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4011 sfx(wpnsfx(wpn),pan(int32_t(x)));
4012 break;
4013 }
4014
4015 case e1t8SHOTS: //Fire Wizzrobe
4016 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,l_up,-1, getUID(),false));
4017 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4018 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4019 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,l_down,-1, getUID(),false));
4020 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4021 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4022 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,r_up,-1, getUID(),false));
4023 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4024 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4025 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,r_down,-1, getUID(),false));
4026 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4027 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4028
4029 [[fallthrough]];
4030 case e1t4SHOTS: //Stalfos 3
4031 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,up,-1, getUID(),false));
4032 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4033 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4034 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,down,-1, getUID(),false));
4035 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4036 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4037 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,left,-1, getUID(),false));
4038 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4039 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4040 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,right,-1, getUID(),false));
4041 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4042 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4043 sfx(wpnsfx(wpn),pan(int32_t(x)));
4044 break;
4045
4046 case e1tSUMMON: // Bat Wizzrobe
4047 {
4048 //al_trace("Summon Bats\n");
4049 //zprint2("Summon Bats\n");
4050 if(dmisc4==0) break; // Summon 0
4051
4052 int32_t bc=0;
4053
4054 for(int32_t gc=0; gc<guys.Count(); gc++)
4055 {
4056 if((((enemy*)guys.spr(gc))->id) == dmisc3)
4057 {
4058 ++bc;
4059 }
4060 }
4061
4062 if(bc<=40) // Not too many enemies
4063 {
4064 int32_t kids = guys.Count();
4065 int32_t bats=(zc_oldrand()%zc_max(1,dmisc4))+1;
4066
4067 for(int32_t i=0; i<bats; i++)
4068 {
4069 //zprint2("summon\n");
4070 //al_trace("summon\n");
4071 if(addchild(x,y,dmisc3,-10, this->script_UID))
4072 {
4073 ((enemy*)guys.spr(kids+i))->count_enemy = false;
4074 //((enemy*)guys.spr(guys.Count()-1))->parent_script_UID = this->script_UID;
4075 //zprint2("Summoner Script UID: %d\n",this->script_UID);
4076
4077 }
4078 }
4079
4080 sfx(get_bit(quest_rules,qr_MORESOUNDS) ? WAV_ZN1SUMMON : WAV_FIRE,pan(int32_t(x)));
4081 }
4082
4083 break;
4084 }
4085
4086 case e1tSUMMONLAYER: // Summoner
4087 {
4088 if(count_layer_enemies()==0)
4089 {
4090 break;
4091 }
4092
4093 int32_t kids = guys.Count();
4094
4095 if(kids<40)
4096 {
4097 int32_t newguys=(zc_oldrand()%3)+1;
4098 bool summoned=false;
4099
4100 for(int32_t i=0; i<newguys; i++)
4101 {
4102 int32_t id2=vbound(random_layer_enemy(),eSTART,eMAXGUYS-1);
4103 int32_t x2=0;
4104 int32_t y2=0;
4105
4106 for(int32_t k=0; k<20; ++k)
4107 {
4108 x2=16*((zc_oldrand()%12)+2);
4109 y2=16*((zc_oldrand()%7)+2);
4110
4111 if((!m_walkflag(x2,y2,0,dir))&&((abs(x2-Hero.getX())>=32)||(abs(y2-Hero.getY())>=32)))
4112 {
4113 //zprint2("summon\n");
4114 //al_trace("summon\n");
4115 if(addchild(x2,y2,get_bit(quest_rules,qr_ENEMIESZAXIS) ? 64 : 0,id2,-10, this->script_UID))
4116 {
4117 ((enemy*)guys.spr(kids+i))->count_enemy = false;
4118 //((enemy*)guys.spr(guys.Count()-1))->parent_script_UID = this->script_UID;
4119 if (get_bit(quest_rules,qr_ENEMIESZAXIS) && (((enemy*)guys.spr(kids+i))->moveflags & FLAG_USE_FAKE_Z))
4120 {
4121 ((enemy*)guys.spr(kids+i))->fakez = 64;
4122 ((enemy*)guys.spr(kids+i))->z = 0;
4123 }
4124 }
4125
4126 summoned=true;
4127 break;
4128 }
4129 }
4130 }
4131
4132 if(summoned)
4133 {
4134 sfx(get_bit(quest_rules,qr_MORESOUNDS) ? WAV_ZN1SUMMON : WAV_FIRE,pan(int32_t(x)));
4135 }
4136 }
4137
4138 break;
4139 }
4140 }
4141 20 }
4142
4143
4144 // Hit the shield(s)?
4145 // Apparently, this function is only used for hookshots...
4146 bool enemy::hitshield(int32_t wpnx, int32_t wpny, int32_t xdir)
4147 {
4148 if(!(family==eeWALK || family==eeFIRE || family==eeOTHER))
4149 return false;
4150
4151 bool ret = false;
4152
4153 // TODO: There must be some bitwise operations that can simplify this...
4154 if(wpny > y) ret = ((flags&inv_front && xdir==down) || (flags&inv_back && xdir==up) || (flags&inv_left && xdir==left) || (flags&inv_right && xdir==right));
4155 else if(wpny < y) ret = ((flags&inv_front && xdir==up) || (flags&inv_back && xdir==down) || (flags&inv_left && xdir==right) || (flags&inv_right && xdir==left));
4156
4157 if(wpnx < x) ret = ret || ((flags&inv_front && xdir==left) || (flags&inv_back && xdir==right) || (flags&inv_left && xdir==up) || (flags&inv_right && xdir==down));
4158 else if(wpnx > x) ret = ret || ((flags&inv_front && xdir==right) || (flags&inv_back && xdir==left) || (flags&inv_left && xdir==down) || (flags&inv_right && xdir==up));
4159
4160 return ret;
4161 }
4162
4163
4164 //! Weapon Editor for 2.6
4165 //To hell with this. I'm writing new functions to resolve weapon type and defence. -Z
4166
4167
4168 //converts a wqeapon ID to its defence index.
4169 76 int32_t weaponToDefence(int32_t wid)
4170 {
4171
2/44
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 44 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
76 switch(wid)
4172 {
4173 case wNone: return -1;
4174 32 case wSword: return edefSWORD;
4175 44 case wBeam: return edefBEAM;
4176 case wBrang: return edefBRANG;
4177 case wBomb: return edefBOMB;
4178 case wSBomb: return edefSBOMB;
4179 case wLitBomb: return edefBOMB;
4180 case wLitSBomb: return edefSBOMB;
4181 case wArrow: return edefARROW;
4182 case wFire: return edefFIRE;
4183 case wWhistle:
4184 {
4185 //al_trace("Weapon resolved as a whistle, using edef: %s\n", "edefWhistle");
4186 return edefWhistle;
4187 }
4188 case wBait: return edefBAIT;
4189 case wWand: return edefWAND;
4190 case wMagic: return edefMAGIC;
4191 case wCatching: return -1;
4192 case wWind: return edefWIND;
4193 case wRefMagic: return edefREFMAGIC;
4194 case wRefFireball: return edefREFBALL;
4195 case wRefRock: return edefREFROCK;
4196 case wHammer: return edefHAMMER;
4197 case wHookshot: return edefHOOKSHOT;
4198 case wHSHandle: return edefHOOKSHOT;
4199 case wHSChain: return edefHOOKSHOT;
4200 case wSSparkle: return edefSPARKLE;
4201 case wFSparkle: return edefSPARKLE;
4202 case wSmack: return -1; // is this the candle object?
4203 case wPhantom: return -1; //engine created visual effects.
4204 case wCByrna: return edefBYRNA;
4205 case wRefBeam: return edefREFBEAM;
4206 case wStomp: return edefSTOMP;
4207 case wScript1: return edefSCRIPT01;
4208 case wScript2: return edefSCRIPT02;
4209 case wScript3: return edefSCRIPT03;
4210 case wScript4: return edefSCRIPT04;
4211 case wScript5: return edefSCRIPT05;
4212 case wScript6: return edefSCRIPT06;
4213 case wScript7: return edefSCRIPT07;
4214 case wScript8: return edefSCRIPT08;
4215 case wScript9: return edefSCRIPT09;
4216 case wScript10: return edefSCRIPT10;
4217 case wIce: return edefICE;
4218 case wSound: return edefSONIC;
4219 case wThrown: return edefTHROWN;
4220 //case wPot: return edefPOT;
4221 // case wLitZap: return edefELECTRIC;
4222 // case wZ3Sword: return edefZ3SWORD;
4223 // case wLASWord: return edefLASWORD;
4224 // case wSpinAttk: return edefSPINATTK;
4225 // case wShield: return edefSHIELD;
4226 // case wTrowel: return edefTROWEL;
4227
4228 default: return -1;
4229 }
4230 76 }
4231
4232 76 int32_t getDefType(weapon *w)
4233 {
4234 76 int32_t id = getWeaponID(w);
4235 76 int32_t edef = weaponToDefence(id);
4236
1/2
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
76 if(edef == edefHOOKSHOT)
4237 {
4238 if(w->family_class == itype_switchhook)
4239 return edefSwitchHook;
4240 }
4241 76 return edef;
4242 76 }
4243
4244 152 int32_t getWeaponID(weapon *w)
4245 {
4246 152 int32_t usewpn = w->useweapon;
4247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 152 times.
152 return (usewpn > 0) ? usewpn : w->id;
4248 }
4249
4250 76 int32_t enemy::resolveEnemyDefence(weapon *w)
4251 {
4252 //sword edef is 9, but we're reading it at 0
4253 //,
4254 76 int32_t weapondef = 0;
4255 76 int32_t wdeftype = getDefType(w);
4256 76 int32_t usedef = w->usedefence;
4257
4258
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
76 if ( usedef > 0 && (wdeftype < 0 || wdeftype >= edefLAST255 || defense[wdeftype] == 0))
4259 {
4260 weapondef = usedef*-1;
4261 }
4262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
76 else if(unsigned(wdeftype) < edefLAST255)
4263 {
4264 76 weapondef = wdeftype;
4265 76 }
4266 76 return weapondef;
4267 }
4268
4269 77 byte get_def_ignrflag(int32_t edef)
4270 {
4271
1/3
✓ Branch 0 taken 77 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
77 switch(edef)
4272 {
4273 case edIGNORE:
4274 case edIGNOREL1:
4275 case edSTUNORIGNORE:
4276 return WPNUNB_IGNR;
4277 case edSTUNORCHINK:
4278 case edCHINK:
4279 case edCHINKL1:
4280 case edCHINKL2:
4281 case edCHINKL4:
4282 case edCHINKL6:
4283 case edCHINKL8:
4284 case edCHINKL10:
4285 case edLEVELCHINK2:
4286 case edLEVELCHINK3:
4287 case edLEVELCHINK4:
4288 case edLEVELCHINK5:
4289 return WPNUNB_BLOCK;
4290 }
4291 77 return 0;
4292 77 }
4293
4294 77 int32_t conv_edef_unblockable(int32_t edef, byte unblockable)
4295 {
4296
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 77 times.
77 if(!(unblockable&get_def_ignrflag(edef))) return edef;
4297 switch(edef)
4298 {
4299 case edIGNORE:
4300 case edIGNOREL1:
4301 case edCHINK:
4302 case edCHINKL1:
4303 case edCHINKL2:
4304 case edCHINKL4:
4305 case edCHINKL6:
4306 case edCHINKL8:
4307 case edCHINKL10:
4308 case edLEVELCHINK2:
4309 case edLEVELCHINK3:
4310 case edLEVELCHINK4:
4311 case edLEVELCHINK5:
4312 return edNORMAL;
4313 case edSTUNORIGNORE:
4314 case edSTUNORCHINK:
4315 return edSTUNONLY;
4316 }
4317 return edef;
4318 77 }
4319
4320 // Do we do damage?
4321 // 0: takehit returns 0
4322 // 1: takehit returns 1
4323 // -1: do damage
4324 //The input from resolveEnemyDefence() for the param 'edef' is negative if a specific defence RESULT is being used.
4325 76 int32_t enemy::defendNew(int32_t wpnId, int32_t *power, int32_t edef, byte unblockable) //May need *wpn to set return on brangs and hookshots
4326 {
4327
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
76 if(switch_hooked) return 0;
4328 76 int32_t tempx = x;
4329 76 int32_t tempy = y;
4330 76 int32_t the_defence = 0;
4331
1/2
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
76 if ( edef < 0 ) //we are using a specific base default defence for a weapon
4332 {
4333 the_defence = edef*-1; //A specific defence type.
4334 }
4335 76 else the_defence = defense[edef];
4336
4337 76 the_defence = conv_edef_unblockable(the_defence, unblockable);
4338
4339
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
76 if(shieldCanBlock && !(unblockable&WPNUNB_SHLD))
4340 {
4341 switch(the_defence)
4342 {
4343 case edIGNORE:
4344 return 0;
4345 case edIGNOREL1:
4346 case edSTUNORIGNORE:
4347 if(*power <= 0)
4348 return 0;
4349 }
4350 sfx(WAV_CHINK,pan(int32_t(x)));
4351 return 1;
4352 }
4353
4354 76 int32_t new_id = id;
4355 76 int32_t effect_type = dmisc15;
4356 76 int32_t delay_timer = 90;
4357 76 enemy *gleeok = NULL;
4358 76 enemy *ptra = NULL;
4359 76 int32_t c = 0;
4360
4361
1/29
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 76 times.
76 switch(the_defence)
4362 {
4363 case edREPLACE:
4364 {
4365 sclk = 0;
4366 if ( dmisc16 > 0 ) new_id = dmisc16;
4367 else new_id = id+1;
4368 if ( new_id > 511 ) new_id = id; //Sanity bound to legal enemy IDs.
4369 if ( dmisc17 > 0 ) delay_timer = dmisc17;
4370 //if ( dmisc18 > 0 ) dummy_wpn_id = dmisc18;
4371
4372 //Z_scripterrlog("new id is %d\n", new_id);
4373 switch(guysbuf[new_id&0xFFF].family)
4374 {
4375 //Fixme: possible enemy memory leak. (minor)
4376 case eeWALK:
4377 {
4378 enemy *e = new eStalfos(x,y,new_id,clk);
4379 guys.add(e);
4380 }
4381 break;
4382
4383 case eeLEV:
4384 {
4385 enemy *e = new eLeever(x,y,new_id,clk);
4386 guys.add(e);
4387 }
4388 break;
4389
4390 case eeTEK:
4391 {
4392 enemy *e = new eTektite(x,y,new_id,clk);
4393 guys.add(e);
4394 }
4395 break;
4396
4397 case eePEAHAT:
4398 {
4399 enemy *e = new ePeahat(x,y,new_id,clk);
4400 guys.add(e);
4401 }
4402 break;
4403
4404 case eeZORA:
4405 {
4406 enemy *e = new eZora(x,y,new_id,clk);
4407 guys.add(e);
4408 }
4409 break;
4410
4411 case eeGHINI:
4412 {
4413 enemy *e = new eGhini(x,y,new_id,clk);
4414 guys.add(e);
4415 }
4416 break;
4417
4418 case eeKEESE:
4419 {
4420 enemy *e = new eKeese(x,y,new_id,clk);
4421 guys.add(e);
4422 }
4423 break;
4424
4425 case eeWIZZ:
4426 {
4427 enemy *e = new eWizzrobe(x,y,new_id,clk);
4428 guys.add(e);
4429 }
4430 break;
4431
4432 case eePROJECTILE:
4433 {
4434 enemy *e = new eProjectile(x,y,new_id,clk);
4435 guys.add(e);
4436 }
4437 break;
4438
4439 case eeWALLM:
4440 {
4441 enemy *e = new eWallM(x,y,new_id,clk);
4442 guys.add(e);
4443 }
4444 break;
4445
4446 case eeAQUA:
4447 {
4448 enemy *e = new eAquamentus(x,y,new_id,clk);
4449 guys.add(e);
4450 e->x = x;
4451 e->y = y;
4452 }
4453 break;
4454
4455 case eeMOLD:
4456 {
4457 enemy *e = new eMoldorm(x,y,new_id,zc_max(1,zc_min(254,guysbuf[new_id&0xFFF].misc1)));
4458 guys.add(e);
4459 e->x = x;
4460 e->y = y;
4461 }
4462 break;
4463
4464 case eeMANHAN:
4465 {
4466 enemy *e = new eManhandla(x,y,new_id,clk);
4467 guys.add(e);
4468 e->x = x;
4469 e->y = y;
4470 }
4471 break;
4472
4473 case eeGLEEOK:
4474 {
4475 *power = 0;
4476 gleeok = new eGleeok(x,y,new_id,guysbuf[new_id&0xFFF].misc1);
4477 guys.add(gleeok);
4478 ((enemy*)guys.spr(guys.Count()-1))->hclk = delay_timer;
4479 //((enemy*)guys.spr(guys.Count()-1))->stunclk = delay_timer;
4480 new_id &= 0xFFF;
4481 int32_t head_cnt = zc_max(1,zc_min(254,guysbuf[new_id&0xFFF].misc1));
4482 Z_scripterrlog("Gleeok head count is %d\n",head_cnt);
4483 for(int32_t i=0; i<head_cnt; i++)
4484 {
4485 //enemy *e = new esGleeok(x,y,new_id+0x1000,clk,gleeok);
4486 if(!guys.add(new esGleeok((zfix)x,(zfix)y,new_id+0x1000,c, gleeok)))
4487 {
4488 al_trace("Gleeok head %d could not be created!\n",i+1);
4489
4490 for(int32_t j=0; j<i+1; j++)
4491 {
4492 guys.del(guys.Count()-1);
4493 }
4494
4495 break;
4496 }
4497 else
4498 {
4499 ((enemy*)guys.spr(guys.Count()-1))->hclk = delay_timer;
4500 //((enemy*)guys.spr(guys.Count()-1))->stunclk = delay_timer;
4501 }
4502
4503 c-=guysbuf[new_id].misc4;
4504 //gleeok->x = x;
4505 //gleeok->y = y;
4506 //gleeok = e;
4507 }
4508 return 1;
4509 }
4510
4511 case eeGHOMA:
4512 {
4513 enemy *e = new eGohma(x,y,new_id,clk);
4514 guys.add(e);
4515 e->x = x;
4516 e->y = y;
4517 }
4518 break;
4519
4520 case eeLANM:
4521 {
4522 enemy *e = new eLanmola(x,y,new_id,zc_max(1,zc_min(253,guysbuf[new_id&0xFFF].misc1)));
4523 guys.add(e);
4524 e->x = x;
4525 e->y = y;
4526 }
4527 break;
4528
4529 case eeGANON:
4530 {
4531 enemy *e = new eGanon(x,y,new_id,clk);
4532 guys.add(e);
4533 e->x = x;
4534 e->y = y;
4535 }
4536 break;
4537
4538 case eeFAIRY:
4539 {
4540 enemy *e = new eItemFairy(x,y,new_id+0x1000*clk,clk);
4541 guys.add(e);
4542 e->x = x;
4543 e->y = y;
4544 }
4545 break;
4546
4547 case eeFIRE:
4548 {
4549 enemy *e = new eFire(x,y,new_id,clk);
4550 guys.add(e);
4551 e->x = x;
4552 e->y = y;
4553 }
4554 break;
4555
4556 case eeOTHER:
4557 {
4558 enemy *e = new eOther(x,y,new_id,clk);
4559 guys.add(e);
4560 e->x = x;
4561 e->y = y;
4562 }
4563 break;
4564
4565 case eeSPINTILE:
4566 {
4567 enemy *e = new eSpinTile(x,y,new_id,clk);
4568 guys.add(e);
4569 e->x = x;
4570 e->y = y;
4571 }
4572 break;
4573
4574 // and these enemies use the misc10/misc2 value
4575 case eeROCK:
4576 {
4577 switch(guysbuf[new_id&0xFFF].misc10)
4578 {
4579 case 1:
4580 {
4581 enemy *e = new eBoulder(x,y,new_id,clk);
4582 guys.add(e);
4583 e->x = x;
4584 e->y = y;
4585 }
4586 break;
4587
4588 case 0:
4589 default:
4590 {
4591 enemy *e = new eRock(x,y,new_id,clk);
4592 guys.add(e);
4593 e->x = x;
4594 e->y = y;
4595 }
4596 break;
4597 }
4598
4599 break;
4600 }
4601
4602 case eeTRAP:
4603 {
4604 switch(guysbuf[new_id&0xFFF].misc2)
4605 {
4606 case 1:
4607 {
4608 enemy *e = new eTrap2(x,y,new_id,clk);
4609 guys.add(e);
4610 e->x = x;
4611 e->y = y;
4612 }
4613 break;
4614
4615 case 0:
4616 default:
4617 {
4618 enemy *e = new eTrap(x,y,new_id,clk);
4619 guys.add(e);
4620 e->x = x;
4621 e->y = y;
4622 }
4623 break;
4624 }
4625
4626 break;
4627 }
4628
4629 case eeDONGO:
4630 {
4631 switch(guysbuf[new_id&0xFFF].misc10)
4632 {
4633 case 1:
4634 {
4635 enemy *e = new eDodongo2(x,y,new_id,clk);
4636 guys.add(e);
4637 e->x = x;
4638 e->y = y;
4639 }
4640 break;
4641
4642 case 0:
4643 default:
4644 {
4645 enemy *e = new eDodongo(x,y,new_id,clk);
4646 guys.add(e);
4647 e->x = x;
4648 e->y = y;
4649 }
4650 break;
4651 }
4652
4653 break;
4654 }
4655
4656 case eeDIG:
4657 {
4658 switch(guysbuf[new_id&0xFFF].misc10)
4659 {
4660 case 1:
4661 {
4662 enemy *e = new eLilDig(x,y,new_id,clk);
4663 guys.add(e);
4664 e->x = x;
4665 e->y = y;
4666 }
4667 break;
4668
4669 case 0:
4670 default:
4671 {
4672 enemy *e = new eBigDig(x,y,new_id,clk);
4673 guys.add(e);
4674 e->x = x;
4675 e->y = y;
4676 }
4677 break;
4678 }
4679
4680 break;
4681 }
4682
4683 case eePATRA:
4684 {
4685 switch(guysbuf[new_id&0xFFF].misc10)
4686 {
4687 case 1:
4688 {
4689 if (get_bit(quest_rules,qr_HARDCODED_BS_PATRA))
4690 {
4691 enemy *e = new ePatraBS(x,y,new_id,clk);
4692 guys.add(e);
4693 e->x = x;
4694 e->y = y;
4695 break;
4696 }
4697 }
4698 [[fallthrough]];
4699 case 0:
4700 default:
4701 {
4702 enemy *e = new ePatra(x,y,new_id,clk);
4703 guys.add(e);
4704 e->x = x;
4705 e->y = y;
4706 }
4707 break;
4708 }
4709
4710 break;
4711 }
4712
4713 case eeGUY:
4714 {
4715 switch(guysbuf[new_id&0xFFF].misc10)
4716 {
4717 case 1:
4718 {
4719 enemy *e = new eTrigger(x,y,new_id,clk);
4720 guys.add(e);
4721 }
4722 break;
4723
4724 case 0:
4725 default:
4726 {
4727 enemy *e = new eNPC(x,y,new_id,clk);
4728 guys.add(e);
4729 }
4730 break;
4731 }
4732
4733 break;
4734 }
4735
4736 case eeSCRIPT01:
4737 case eeSCRIPT02:
4738 case eeSCRIPT03:
4739 case eeSCRIPT04:
4740 case eeSCRIPT05:
4741 case eeSCRIPT06:
4742 case eeSCRIPT07:
4743 case eeSCRIPT08:
4744 case eeSCRIPT09:
4745 case eeSCRIPT10:
4746 case eeSCRIPT11:
4747 case eeSCRIPT12:
4748 case eeSCRIPT13:
4749 case eeSCRIPT14:
4750 case eeSCRIPT15:
4751 case eeSCRIPT16:
4752 case eeSCRIPT17:
4753 case eeSCRIPT18:
4754 case eeSCRIPT19:
4755 case eeSCRIPT20:
4756 {
4757 enemy *e = new eScript(x,y,new_id,clk);
4758 guys.add(e);
4759 e->x = x;
4760 e->y = y;
4761 break;
4762 }
4763
4764
4765 case eeFFRIENDLY01:
4766 case eeFFRIENDLY02:
4767 case eeFFRIENDLY03:
4768 case eeFFRIENDLY04:
4769 case eeFFRIENDLY05:
4770 case eeFFRIENDLY06:
4771 case eeFFRIENDLY07:
4772 case eeFFRIENDLY08:
4773 case eeFFRIENDLY09:
4774 case eeFFRIENDLY10:
4775 {
4776 enemy *e = new eFriendly(x,y,new_id,clk);
4777 guys.add(e);
4778 e->x = x;
4779 e->y = y;
4780 break;
4781 }
4782
4783
4784 default: break;
4785 }
4786
4787 // add segments of segmented enemies
4788 int32_t c=0;
4789
4790 switch(guysbuf[new_id&0xFFF].family)
4791 {
4792 case eeMOLD:
4793 {
4794 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
4795 new_id &= 0xFFF;
4796
4797 for(int32_t i=0; i<zc_max(1,zc_min(254,guysbuf[new_id].misc1)); i++)
4798 {
4799 //christ this is messy -DD
4800 int32_t segclk = -i*((int32_t)(8.0/(zslongToFix(guysbuf[new_id&0xFFF].step*100))));
4801
4802 if(!guys.add(new esMoldorm((zfix)x,(zfix)y,new_id+0x1000,segclk)))
4803 {
4804 al_trace("Moldorm segment %d could not be created!\n",i+1);
4805
4806 for(int32_t j=0; j<i+1; j++)
4807 guys.del(guys.Count()-1);
4808
4809 return 0;
4810 }
4811
4812 if(i>0)
4813 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
4814
4815
4816 }
4817
4818 break;
4819 }
4820
4821 case eeLANM:
4822 {
4823 new_id &= 0xFFF;
4824 int32_t shft = guysbuf[new_id].misc2;
4825 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
4826 enemy *e = new esLanmola((zfix)x,(zfix)y,new_id+0x1000,0);
4827
4828 if(!guys.add(e))
4829 {
4830 al_trace("Lanmola segment 1 could not be created!\n");
4831 guys.del(guys.Count()-1);
4832 return 0;
4833 }
4834 e->x = x;
4835 e->y = y;
4836
4837
4838
4839 for(int32_t i=1; i<zc_max(1,zc_min(253,guysbuf[new_id&0xFFF].misc1)); i++)
4840 {
4841 enemy *e2 = new esLanmola((zfix)x,(zfix)y,new_id+0x2000,-(i<<shft));
4842 if(!guys.add(e2))
4843 {
4844 al_trace("Lanmola segment %d could not be created!\n",i+1);
4845
4846 for(int32_t j=0; j<i+1; j++)
4847 guys.del(guys.Count()-1);
4848
4849 return 0;
4850 }
4851 e2->x = x;
4852 e2->y = y;
4853
4854 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
4855
4856 }
4857 }
4858 break;
4859
4860 case eeMANHAN:
4861 new_id &= 0xFFF;
4862
4863 for(int32_t i=0; i<((!(guysbuf[new_id].misc2))?4:8); i++)
4864 {
4865 if(!guys.add(new esManhandla((zfix)x,(zfix)y,new_id+0x1000,i)))
4866 {
4867 al_trace("Manhandla head %d could not be created!\n",i+1);
4868
4869 for(int32_t j=0; j<i+1; j++)
4870 {
4871 guys.del(guys.Count()-1);
4872 }
4873
4874 return 0;
4875 }
4876
4877
4878 ((enemy*)guys.spr(guys.Count()-1))->frate=guysbuf[new_id].misc1;
4879 }
4880
4881 break;
4882
4883 case eeGLEEOK:
4884 {
4885 /*
4886 new_id &= 0xFFF;
4887 int32_t head_cnt = zc_max(1,zc_min(254,guysbuf[new_id&0xFFF].misc1));
4888 Z_scripterrlog("Gleeok head count is %d\n",head_cnt);
4889 for(int32_t i=0; i<head_cnt; i++)
4890 {
4891 //enemy *e = new esGleeok(x,y,new_id+0x1000,clk,gleeok);
4892 if(!guys.add(new esGleeok((zfix)x,(zfix)y,new_id+0x1000,c, gleeok)))
4893 {
4894 al_trace("Gleeok head %d could not be created!\n",i+1);
4895
4896 for(int32_t j=0; j<i+1; j++)
4897 {
4898 guys.del(guys.Count()-1);
4899 }
4900
4901 break;
4902 }
4903
4904 c-=guysbuf[new_id].misc4;
4905 */
4906
4907 // }
4908 }
4909 break;
4910
4911
4912 case eePATRA:
4913 {
4914 new_id &= 0xFFF;
4915 int32_t outeyes = 0;
4916 ptra = new ePatraBS((zfix)x,(zfix)y,id,clk);
4917
4918 for(int32_t i=0; i<zc_min(254,guysbuf[new_id&0xFFF].misc1); i++)
4919 {
4920 if(!((guysbuf[new_id].misc10&&get_bit(quest_rules,qr_HARDCODED_BS_PATRA))?guys.add(new esPatraBS((zfix)x,(zfix)y,new_id+0x1000,i,ptra)):guys.add(new esPatra((zfix)x,(zfix)y,new_id+0x1000,i,ptra))))
4921 {
4922 al_trace("Patra outer eye %d could not be created!\n",i+1);
4923
4924 for(int32_t j=0; j<i+1; j++)
4925 guys.del(guys.Count()-1);
4926
4927 return 0;
4928 }
4929 else
4930 outeyes++;
4931
4932
4933 }
4934
4935 for(int32_t i=0; i<zc_min(254,guysbuf[new_id&0xFFF].misc2); i++)
4936 {
4937 if(!guys.add(new esPatra((zfix)x,(zfix)y,new_id+0x1000,i,ptra)))
4938 {
4939 al_trace("Patra inner eye %d could not be created!\n",i+1);
4940
4941 for(int32_t j=0; j<i+1+zc_min(254,outeyes); j++)
4942 guys.del(guys.Count()-1);
4943
4944 return 0;
4945 }
4946
4947
4948 }
4949 delete ptra;
4950 break;
4951 }
4952 }
4953
4954
4955
4956 ((enemy*)guys.spr(guys.Count()-1))->count_enemy = true;
4957 ((enemy*)guys.spr(guys.Count()-1))->stunclk = delay_timer;
4958 ((enemy*)guys.spr(guys.Count()-1))->dir = this->dir;
4959 ((enemy*)guys.spr(guys.Count()-1))->scale = this->scale;
4960 ((enemy*)guys.spr(guys.Count()-1))->angular = this->angular;
4961 ((enemy*)guys.spr(guys.Count()-1))->angle = this->angle;
4962 ((enemy*)guys.spr(guys.Count()-1))->rotation = this->rotation;
4963 //((enemy*)guys.spr(guys.Count()-1))->mainguy = this->mainguy; //This might mean that it is a core.
4964 ((enemy*)guys.spr(guys.Count()-1))->itemguy = this->itemguy;
4965 ((enemy*)guys.spr(guys.Count()-1))->leader = this->leader;
4966 ((enemy*)guys.spr(guys.Count()-1))->hclk = delay_timer;
4967 ((enemy*)guys.spr(guys.Count()-1))->script_spawned = this->script_spawned;
4968 ((enemy*)guys.spr(guys.Count()-1))->script_UID = this->script_UID;
4969 ((enemy*)guys.spr(guys.Count()-1))->sclk = 0;
4970
4971
4972 item_set = 0; //Do not make a drop.
4973
4974 switch(effect_type)
4975 {
4976 case -7:
4977 {
4978 weapon *w = new weapon(x,y-fakez,z,wBomb,0,wdp,0,-1,getUID(),false, 0);
4979 Lwpns.add(w);
4980 break;
4981 }
4982 case -6:
4983 {
4984 weapon *w = new weapon(x,y-fakez,z,wSBomb,0,wdp,0,-1,getUID(),false, 0);
4985 Lwpns.add(w);
4986 break;
4987 }
4988 case -5:
4989 {
4990 weapon *w = new weapon(x,y-fakez,z,wBomb,effect_type,0,0,Hero.getUID(), txsz, tysz);
4991 Lwpns.add(w);
4992 break;
4993 }
4994 case -4:
4995 {
4996 weapon *w = new weapon(x,y-fakez,z,wSBomb,effect_type,0,0,Hero.getUID(), txsz, tysz);
4997 Lwpns.add(w);
4998 break;
4999 }
5000 case -3: explode(1); break;
5001 case -2: explode(2); break;
5002 case -1: explode(0); break;
5003 case 0: break;
5004
5005 default:
5006 {
5007 //Dummy weapon function
5008 if ( effect_type > 255 ) effect_type = 0; //Sanity bound the sprite ID.
5009 weapon *w = new weapon(x,y-fakez,z,wSSparkle,effect_type,0,0,Hero.getUID(), txsz, tysz,0,0,0,0,0,0,0);
5010 Lwpns.add(w);
5011 break;
5012 }
5013 }
5014
5015
5016 yofs = -32768;
5017 switch(guysbuf[new_id&0xFFF].family)
5018 {
5019 case eeGLEEOK:
5020 {
5021 Z_scripterrlog("Replacing a gleeok.\n");
5022 enemy *tempenemy = (enemy *) guys.getByUID(parentCore);
5023 hp = -999;
5024 tempenemy->hp = -999;
5025 break;
5026
5027 }
5028 default:
5029 hp = -1000; break;
5030 }
5031 ++game->guys[(currmap*MAPSCRSNORMAL)+currscr];
5032 return 1;
5033
5034 }
5035 case edSPLIT:
5036 {
5037 //int32_t ex = x; int32_t ey = y;
5038 //al_trace("edSplit dmisc3: %d\n", dmisc3);
5039 //al_trace("edSplit dmisc4: %d\n", dmisc4);
5040 /*
5041 if ( txsx > 1 )
5042 {
5043 ex += ( txsz-1 ) * 8; //from its middle
5044 }
5045 if ( tysx > 1 )
5046 {
5047 ey += ( tysz-1 ) * 8; //from its middle
5048 }
5049 */
5050 for ( int32_t q = 0; q < dmisc4; q++ )
5051 {
5052
5053 //addenemy((x+(txsz*16)/2),(y+(tysz*16)/2),dmisc3+0x1000,-15);
5054 addenemy(
5055 //ex,ey,
5056 x,y,
5057 dmisc3+0x1000,-15);
5058 //addenemy(ex,ey,dmisc3,0);
5059
5060 }
5061 item_set = 0; //Do not make a drop.
5062 hp = -1000;
5063 return -1;
5064
5065 }
5066 case edSUMMON:
5067 {
5068
5069
5070 //al_trace("edSplit dmisc3: %d\n", dmisc3);
5071 //al_trace("edSplit dmisc4: %d\n", dmisc4);
5072 int32_t summon_count = (zc_oldrand()%dmisc4)+1;
5073 for ( int32_t q = 0; q < summon_count; q++ )
5074 {
5075 int32_t x2=16*((zc_oldrand()%12)+2);
5076 int32_t y2=16*((zc_oldrand()%7)+2);
5077 addenemy(
5078 //(x+(txsz*16)/2),(y+(tysz*16)/2)
5079 x2,y2,
5080 dmisc3+0x1000,-15);
5081 //addenemy(ex,ey,dmisc3,0);
5082
5083 }
5084 sfx(get_bit(quest_rules,qr_MORESOUNDS) ? WAV_ZN1SUMMON : WAV_FIRE,pan(int32_t(x)));
5085 return -1;
5086
5087 }
5088
5089 case edEXPLODESMALL:
5090 {
5091 weapon *ew=new weapon(x,y-fakez,z, ewBomb, 0, dmisc4, dir,-1,getUID(),false);
5092 Ewpns.add(ew);
5093 item_set = 0; //Should we make a drop?
5094 hp = -1000;
5095 return -1;
5096 }
5097
5098
5099 case edEXPLODEHARMLESS:
5100 {
5101 weapon *ew=new weapon(x,y-fakez,z, ewSBomb, 0, dmisc4, dir,-1,getUID(),false);
5102 Ewpns.add(ew);
5103 ew->hyofs = -32768;
5104 item_set = 0; //Should we make a drop?
5105 hp = -1000;
5106 return -1;
5107 }
5108
5109
5110 case edEXPLODELARGE:
5111 {
5112 weapon *ew=new weapon(x,y-fakez,z, ewSBomb, 0, dmisc4, dir,-1,getUID(),false);
5113 Ewpns.add(ew);
5114
5115 hp = -1000;
5116 return -1;
5117 }
5118
5119
5120 case edTRIGGERSECRETS:
5121 {
5122 hidden_entrance(0, true, false, -4);
5123 return -1;
5124 }
5125
5126 case edSTUNORCHINK:
5127 if (stunclk && get_bit(quest_rules, qr_NO_STUNLOCK))
5128 {
5129 sfx(WAV_CHINK,pan(int32_t(x)));
5130 return 1;
5131 }
5132 else if(*power <= 0)
5133 {
5134 //al_trace("defendNew() is at: %s\n", "returning edSTUNORCHINK");
5135 sfx(WAV_CHINK,pan(int32_t(x)));
5136 return 1;
5137 }
5138 [[fallthrough]];
5139
5140 case edSTUNORIGNORE:
5141 if (stunclk && get_bit(quest_rules, qr_NO_STUNLOCK))
5142 {
5143 sfx(WAV_CHINK,pan(int32_t(x)));
5144 return 1;
5145 }
5146 else if(*power <= 0)
5147 return 0;
5148 [[fallthrough]];
5149
5150 case edSTUNONLY:
5151 if((wpnId==wFire || wpnId==wBomb || wpnId==wSBomb || wpnId==wHookshot || wpnId==wSword) && stunclk>=159)
5152 {
5153 //al_trace("enemy::defend(), edSTUNONLY found a weapon of type FIRE, BOMB, SBOMB, HOOKSHOT, or SWORD:, with wpnId: \n", wpnId);
5154 // Z_message("enemy::defend(), edSTUNONLY found a weapon of type FIRE, BOMB, SBOMB, HOOKSHOT, or SWORD:, with wpnId: \n", wpnId);
5155 return 1;
5156 }
5157 if (stunclk && get_bit(quest_rules, qr_NO_STUNLOCK))
5158 {
5159 sfx(WAV_CHINK,pan(int32_t(x)));
5160 return 1;
5161 }
5162 else
5163 {
5164 stunclk=160;
5165 sfx(WAV_EHIT,pan(int32_t(x)));
5166
5167 return 1;
5168 }
5169
5170 case edCHINKL1:
5171 if(*power >= 1*game->get_hero_dmgmult()) break;
5172 [[fallthrough]];
5173 case edCHINKL2:
5174 if(*power >= 2*game->get_hero_dmgmult()) break;
5175 [[fallthrough]];
5176 case edCHINKL4:
5177 if(*power >= 4*game->get_hero_dmgmult()) break;
5178 [[fallthrough]];
5179 case edCHINKL6:
5180 if(*power >= 6*game->get_hero_dmgmult()) break;
5181 [[fallthrough]];
5182 case edCHINKL8:
5183 if(*power >= 8*game->get_hero_dmgmult()) break;
5184 [[fallthrough]];
5185 case edCHINKL10:
5186 if(*power >= 10*game->get_hero_dmgmult()) break;
5187 [[fallthrough]];
5188 case edCHINK:
5189 //al_trace("defendNew() is at: %s\n", "returning edCHINK");
5190 sfx(WAV_CHINK,pan(int32_t(x)));
5191 return 1;
5192
5193 case edIGNOREL1:
5194 if(*power > 0) break;
5195 [[fallthrough]];
5196
5197 case edIGNORE:
5198 return 0;
5199
5200 case ed1HKO:
5201 *power = hp;
5202 return -2;
5203
5204 case ed2x:
5205 {
5206 *power = zc_max(1,*power*2);
5207 //int32_t pow = *power;
5208 //*power = vbound((pow*2),0,214747);
5209 return -1;
5210 }
5211 case ed3x:
5212 {
5213 *power = zc_max(1,*power*3);
5214 //int32_t pow = *power;
5215 //*power = vbound((pow*3),0,214747);
5216 return -1;
5217 }
5218
5219 case ed4x:
5220 {
5221 *power = zc_max(1,*power*4);
5222 //int32_t pow = *power;
5223 //*power = vbound((pow*4),0,214747);
5224 return -1;
5225 }
5226
5227
5228 case edHEAL:
5229 { //Probably needs its own function, or routine in the damage functuon to heal if power is negative.
5230 //int32_t pow = *power;
5231 //*power = vbound((pow*-1),0,214747);
5232 //break;
5233 *power = zc_min(0,*power*-1);
5234 return -1;
5235 }
5236 /*
5237 case edLEVELDAMAGE:
5238 {
5239 int32_t pow = *power;
5240 int32_t lvl = *level;
5241 *power = vbound((pow*lvl),0,214747);
5242 break;
5243 }
5244 case edLEVELREDUCTION:
5245 {
5246 int32_t pow = *power;
5247 int32_t lvl = *level;
5248 *power = vbound((pow/lvl),0,214747);
5249 break;
5250 }
5251 */
5252
5253 case edQUARTDAMAGE:
5254 *power = zc_max(1,*power/2);
5255
5256 [[fallthrough]];
5257 case edHALFDAMAGE:
5258 *power = zc_max(1,*power/2);
5259 break;
5260
5261 case edSWITCH:
5262 {
5263 if(Hero.switchhookclk) return 0; //Already switching!
5264 switch(family)
5265 {
5266 case eeAQUA: case eeMOLD: case eeDONGO: case eeMANHAN: case eeGLEEOK:
5267 case eeDIG: case eeGHOMA: case eeLANM: case eePATRA: case eeGANON:
5268 return 0;
5269 }
5270 hooked_combopos = -1;
5271 hooked_layerbits = 0;
5272 switching_object = this;
5273 switch_hooked = true;
5274 Hero.doSwitchHook(game->get_switchhookstyle());
5275 if(QMisc.miscsfx[sfxSWITCHED])
5276 sfx(QMisc.miscsfx[sfxSWITCHED],int32_t(x));
5277 return 1;
5278 }
5279
5280 case 0:
5281 {
5282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
76 if(edef == edefSwitchHook)
5283 return -1;
5284
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
76 if (stunclk && get_bit(quest_rules, qr_NO_STUNLOCK) && *power == 0)
5285 {
5286 sfx(WAV_CHINK,pan(int32_t(x)));
5287 return 1;
5288 }
5289
5290 }
5291 76 }
5292
5293 76 return -1;
5294 76 }
5295
5296 76 int32_t enemy::defendNewInt(int32_t wpnId, int32_t *power, int32_t edef, byte unblockable, weapon* w)
5297 {
5298 76 std::vector<int32_t> &ev = FFCore.eventData;
5299 76 ev.clear();
5300 76 ev.push_back(*power*10000);
5301 76 ev.push_back(edef*10000);
5302 76 ev.push_back(unblockable*10000);
5303 76 ev.push_back(wpnId*10000);
5304 76 ev.push_back(0);
5305 76 ev.push_back(getUID());
5306
1/2
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
76 ev.push_back(w?w->getUID():0);
5307
5308 76 throwGenScriptEvent(GENSCR_EVENT_ENEMY_HIT1);
5309 76 *power = ev[0]/10000;
5310 76 edef = ev[1]/10000;
5311 76 unblockable = byte(ev[2]/10000);
5312 76 wpnId = ev[3] / 10000;
5313 76 bool nullify = ev[4]!=0;
5314 76 ev.clear();
5315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
76 if(nullify) return 0;
5316
5317 76 int32_t ret = defendNew(wpnId, power, edef, unblockable);
5318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
76 if(ret != -1) return ret;
5319 76 ev.push_back(*power*10000);
5320 76 ev.push_back(edef*10000);
5321 76 ev.push_back(unblockable*10000);
5322 76 ev.push_back(wpnId*10000);
5323 76 ev.push_back(0);
5324 76 ev.push_back(getUID());
5325
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
76 ev.push_back(w?w->getUID():0);
5326
5327 76 throwGenScriptEvent(GENSCR_EVENT_ENEMY_HIT2);
5328 76 *power = ev[0]/10000;
5329 76 nullify = ev[4]!=0;
5330 76 ev.clear();
5331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
76 if(nullify) return 0;
5332 76 return -1;
5333 76 }
5334
5335 76 int32_t enemy::defenditemclassNew(int32_t wpnId, int32_t *power, weapon *w)
5336 {
5337 76 int32_t wid = getWeaponID(w);
5338
5339 76 int32_t edef = resolveEnemyDefence(w);
5340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
76 if(QHeader.zelda_version > 0x250)
5341 return defendNewInt(wid, power, edef, w->unblockable, w);
5342
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
76 switch(wid)
5343 {
5344 case wScript1: case wScript2: case wScript3: case wScript4: case wScript5:
5345 case wScript6: case wScript7: case wScript8: case wScript9: case wScript10:
5346 return defend(wpnId, power, edefSCRIPT);
5347
5348 case wWhistle:
5349 return -1;
5350
5351 default:
5352 76 return defendNewInt(wid, power, edef, w->unblockable, w);
5353 }
5354 76 }
5355
5356
5357 // Check defenses without actually acting on them.
5358 bool enemy::candamage(int32_t power, int32_t edef, byte unblockable)
5359 {
5360 switch(defense[edef])
5361 {
5362 case edSTUNONLY:
5363 return false;
5364 case edSTUNORCHINK:
5365 case edCHINK:
5366 return unblockable&WPNUNB_BLOCK;
5367 case edSTUNORIGNORE:
5368 case edIGNORE:
5369 return unblockable&WPNUNB_IGNR;
5370
5371 case edIGNOREL1:
5372 return (unblockable&WPNUNB_IGNR) || power >= 1*game->get_hero_dmgmult();
5373 case edCHINKL1:
5374 return (unblockable&WPNUNB_BLOCK) || power >= 1*game->get_hero_dmgmult();
5375
5376 case edCHINKL2:
5377 return (unblockable&WPNUNB_BLOCK) || power >= 2*game->get_hero_dmgmult();
5378
5379 case edCHINKL4:
5380 return (unblockable&WPNUNB_BLOCK) || power >= 4*game->get_hero_dmgmult();
5381
5382 case edCHINKL6:
5383 return (unblockable&WPNUNB_BLOCK) || power >= 6*game->get_hero_dmgmult();
5384
5385 case edCHINKL8:
5386 return (unblockable&WPNUNB_BLOCK) || power >= 8*game->get_hero_dmgmult();
5387 }
5388
5389 return true;
5390 }
5391
5392 // Do we do damage?
5393 // 0: takehit returns 0
5394 // 1: takehit returns 1
5395 // -1: do damage
5396 int32_t enemy::defend(int32_t wpnId, int32_t *power, int32_t edef)
5397 {
5398 if(shieldCanBlock)
5399 {
5400 switch(defense[edef])
5401 {
5402 case edIGNORE:
5403 return 0;
5404 case edIGNOREL1:
5405 case edSTUNORIGNORE:
5406 if(*power <= 0)
5407 return 0;
5408 }
5409
5410 sfx(WAV_CHINK,pan(int32_t(x)));
5411 return 1;
5412 }
5413
5414 switch(defense[edef])
5415 {
5416 case edSTUNORCHINK:
5417 if(*power <= 0)
5418 {
5419 sfx(WAV_CHINK,pan(int32_t(x)));
5420 return 1;
5421 }
5422
5423 [[fallthrough]];
5424 case edSTUNORIGNORE:
5425 if(*power <= 0)
5426 return 0;
5427
5428 [[fallthrough]];
5429 case edSTUNONLY:
5430 if((wpnId==wFire || wpnId==wBomb || wpnId==wSBomb || wpnId==wHookshot || wpnId==wSword) && stunclk>=159)
5431 return 1;
5432
5433 stunclk=160;
5434 sfx(WAV_EHIT,pan(int32_t(x)));
5435 return 1;
5436
5437 case edFREEZE:
5438 frozenclock=-1;
5439 //sfx(WAV_FREEZE,pan(int32_t(x)));
5440 return 1;
5441
5442 case edCHINKL1:
5443 if(*power >= 1*game->get_hero_dmgmult()) break;
5444 [[fallthrough]];
5445 case edCHINKL2:
5446 if(*power >= 2*game->get_hero_dmgmult()) break;
5447 [[fallthrough]];
5448 case edCHINKL4:
5449 if(*power >= 4*game->get_hero_dmgmult()) break;
5450 [[fallthrough]];
5451 case edCHINKL6:
5452 if(*power >= 6*game->get_hero_dmgmult()) break;
5453 [[fallthrough]];
5454 case edCHINKL8:
5455 if(*power >= 8*game->get_hero_dmgmult()) break;
5456 [[fallthrough]];
5457 case edCHINKL10:
5458 if(*power >= 10*game->get_hero_dmgmult()) break;
5459 [[fallthrough]];
5460 case edCHINK:
5461 sfx(WAV_CHINK,pan(int32_t(x)));
5462 return 1;
5463 case edTRIGGERSECRETS:
5464 hidden_entrance(0, true, false, -4);
5465 break;
5466
5467 case edIGNOREL1:
5468 if(*power > 0) break;
5469 [[fallthrough]];
5470 case edIGNORE:
5471 return 0;
5472
5473 case ed1HKO:
5474 *power = hp;
5475 return -2;
5476
5477 case ed2x:
5478 {
5479 *power = zc_max(1,*power*2);
5480 //int32_t pow = *power;
5481 //*power = vbound((pow*2),0,214747);
5482 return -1;
5483 }
5484 case ed3x:
5485 {
5486 *power = zc_max(1,*power*3);
5487 //int32_t pow = *power;
5488 //*power = vbound((pow*3),0,214747);
5489 return -1;
5490 }
5491
5492 case ed4x:
5493 {
5494 *power = zc_max(1,*power*4);
5495 //int32_t pow = *power;
5496 //*power = vbound((pow*4),0,214747);
5497 return -1;
5498 }
5499
5500
5501 case edHEAL:
5502 { //Probably needs its own function, or routine in the damage functuon to heal if power is negative.
5503 //int32_t pow = *power;
5504 //*power = vbound((pow*-1),0,214747);
5505 //break;
5506 *power = zc_min(0,*power*-1);
5507 return -1;
5508 }
5509 /*
5510 case edLEVELDAMAGE:
5511 {
5512 int32_t pow = *power;
5513 int32_t lvl = *level;
5514 *power = vbound((pow*lvl),0,214747);
5515 break;
5516 }
5517 case edLEVELREDUCTION:
5518 {
5519 int32_t pow = *power;
5520 int32_t lvl = *level;
5521 *power = vbound((pow/lvl),0,214747);
5522 break;
5523 }
5524 */
5525
5526
5527 case edQUARTDAMAGE:
5528 *power = zc_max(1,*power/2);
5529
5530 [[fallthrough]];
5531 case edHALFDAMAGE:
5532 *power = zc_max(1,*power/2);
5533 break;
5534 }
5535
5536 return -1;
5537 }
5538
5539 // Defend against a particular item class.
5540 int32_t enemy::defenditemclass(int32_t wpnId, int32_t *power)
5541 {
5542 int32_t def=-1;
5543
5544 switch(wpnId)
5545 {
5546 // These first 2 are only used by Gohma... enemy::takehit() has complicated stun-calculation code for these.
5547 case wBrang:
5548 def = defend(wpnId, power, edefBRANG);
5549 break;
5550
5551 case wHookshot:
5552 def = defend(wpnId, power, edefHOOKSHOT);
5553 break;
5554
5555 // Anyway...
5556 case wBomb:
5557 def = defend(wpnId, power, edefBOMB);
5558 break;
5559
5560 case wSBomb:
5561 def = defend(wpnId, power, edefSBOMB);
5562 break;
5563
5564 case wArrow:
5565 def = defend(wpnId, power, edefARROW);
5566 break;
5567
5568 case wFire:
5569 def = defend(wpnId, power, edefFIRE);
5570 break;
5571
5572 case wWand:
5573 def = defend(wpnId, power, edefWAND);
5574 break;
5575
5576 case wMagic:
5577 def = defend(wpnId, power, edefMAGIC);
5578 break;
5579
5580 case wHammer:
5581 def = defend(wpnId, power, edefHAMMER);
5582 break;
5583
5584 case wSword:
5585 def = defend(wpnId, power, edefSWORD);
5586 break;
5587
5588 case wBeam:
5589 def = defend(wpnId, power, edefBEAM);
5590 break;
5591
5592 case wRefBeam:
5593 def = defend(wpnId, power, edefREFBEAM);
5594 break;
5595
5596 case wRefMagic:
5597 def = defend(wpnId, power, edefREFMAGIC);
5598 break;
5599
5600 case wRefFireball:
5601 def = defend(wpnId, power, edefREFBALL);
5602 break;
5603
5604 case wRefRock:
5605 def = defend(wpnId, power, edefREFROCK);
5606 break;
5607
5608 case wStomp:
5609 def = defend(wpnId, power, edefSTOMP);
5610 break;
5611
5612 case wCByrna:
5613 def = defend(wpnId, power, edefBYRNA);
5614 break;
5615
5616 case wScript1:
5617 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT01);
5618 else def = defend(wpnId, power, edefSCRIPT);
5619 break;
5620
5621 case wScript2:
5622 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT02);
5623 else def = defend(wpnId, power, edefSCRIPT);
5624 break;
5625
5626 case wScript3:
5627 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT03);
5628 else def = defend(wpnId, power, edefSCRIPT);
5629 break;
5630
5631 case wScript4:
5632 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT04);
5633 else def = defend(wpnId, power, edefSCRIPT);
5634 break;
5635
5636 case wScript5:
5637 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT05);
5638 else def = defend(wpnId, power, edefSCRIPT);
5639 break;
5640
5641 case wScript6:
5642 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT06);
5643 else def = defend(wpnId, power, edefSCRIPT);
5644 break;
5645
5646 case wScript7:
5647 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT07);
5648 else def = defend(wpnId, power, edefSCRIPT);
5649 break;
5650
5651 case wScript8:
5652 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT08);
5653 else def = defend(wpnId, power, edefSCRIPT);
5654 break;
5655
5656 case wScript9:
5657 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT09);
5658 else def = defend(wpnId, power, edefSCRIPT);
5659 break;
5660
5661 case wScript10:
5662 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT10);
5663 else def = defend(wpnId, power, edefSCRIPT);
5664 break;
5665
5666 case wWhistle:
5667 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefWhistle);
5668 else break;
5669 break;
5670
5671
5672 //!ZoriaRPG : We need some special cases here, to ensure that old script defs don;t break.
5673 //Probably best to do this from the qest file, loading the values of Script(generic) into each
5674 //of the ten if the quest version is lower than N.
5675 //Either that, or we need a boolean flag to set int32_t he enemy editor, or by ZScript that changes this behaviour.
5676 //such as bool UseSeparatedScriptDefences. hah.
5677 default:
5678 //if(wpnId>=wScript1 && wpnId<=wScript10)
5679 // {
5680 // def = defend(wpnId, power, edefSCRIPT);
5681 // }
5682 // }
5683
5684 break;
5685 }
5686
5687 return def;
5688 }
5689
5690 // take damage or ignore it
5691 // -1: damage (if any) dealt
5692 // 1: blocked
5693 // 0: weapon passes through unhindered
5694 76 int32_t enemy::takehit(weapon *w)
5695 {
5696
2/4
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 76 times.
76 if(fallclk||drownclk) return 0;
5697 76 int32_t wpnId = w->id;
5698 //al_trace("takehit() wpnId is %d\n",wpnId);
5699 //if ( wpnId == wWhistle ) al_trace("Whistle weapon in %s\n", "takehit");
5700 76 int32_t power = w->power;
5701 76 int32_t wpnx = w->x;
5702 76 int32_t wpny = w->y;
5703 76 int32_t enemyHitWeapon = w->parentitem;
5704 int32_t wpnDir;
5705 76 int32_t parent_item = w->parentitem;
5706
5707 //if ( parent_item > -1 )
5708 //{
5709 // if ( itemsbuf[parent_item].useweapon > 0 /*&& wpnId != wWhistle*/ )
5710 // {
5711 // wpnId = itemsbuf[parent_item].useweapon;
5712 // }
5713
5714 //}
5715 //if ( parent_item == -1 && w->ScriptGenerated )
5716 //{
5717 // if ( w->useweapon > 0 /*&& wpnId != wWhistle*/ )
5718 // {
5719 // wpnId = w->useweapon;
5720 // }
5721
5722 //}
5723 //al_trace("takehit wpnId is: %d\n",wpnId);
5724
5725 //Shoud be set from idata from the weapon::weaon constructor. -Z
5726
1/2
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
76 if ( w->useweapon > 0 /*&& wpnId != wWhistle*/ )
5727 {
5728 wpnId = w->useweapon;
5729 }
5730
5731 //al_trace("takehit() useweapon is %d\n",itemsbuf[parent_item].useweapon);
5732
5733 //Weapon Editor -Z
5734
5735
5736 // If it's a boomerang that just bounced, use the opposite direction;
5737 // otherwise, it might bypass a shield. This probably won't handle
5738 // every case correctly, but it's better than having shields simply
5739 // not work against boomerangs.
5740
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
76 if(w->id==wBrang && w->misc==1 && w->clk2>=256 && w->clk2<264)
5741 wpnDir = oppositeDir[w->dir];
5742 else
5743 76 wpnDir = w->dir;
5744
5745
4/8
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 76 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 76 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 76 times.
76 if(dying || clk<0 || hclk>0 || superman)
5746 {
5747 return 0;
5748 }
5749
5750 //Prevent boomerang from writing to hitby[] for more than one frame.
5751 //This also prevents stunlock.
5752 //if ( stunclk > 0 ) return 0;
5753 //this needs a rule for boomerangs that cannot stunlock!
5754 //further, bouncing weapons should probably SFX_CHINK and bounce here.
5755 //sigh.
5756
5757 76 int32_t ret = -1;
5758
5759 // This obscure quest rule...
5760
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
76 if(get_bit(quest_rules,qr_BOMBDARKNUTFIX) && (wpnId==wBomb || wpnId==wSBomb))
5761 {
5762 double _MSVC2022_tmp1, _MSVC2022_tmp2;
5763 double ddir=atan2_MSVC2022_FIX(double(wpny-y),double(x-wpnx));
5764 wpnDir=zc_oldrand()&3;
5765
5766 if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
5767 {
5768 wpnDir=down;
5769 }
5770 else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
5771 {
5772 wpnDir=right;
5773 }
5774 else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/4)))
5775 {
5776 wpnDir=up;
5777 }
5778 else
5779 {
5780 wpnDir=left;
5781 }
5782 }
5783
5784 76 int32_t xdir = dir;
5785 76 shieldCanBlock=false;
5786
5787 //if (family==eeFLOAT && flags&(inv_front|inv_back_inv_left|inv_right)) xdir=down;
5788
2/4
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 76 times.
76 if(!(w->unblockable&WPNUNB_BLOCK)&&((wpnId==wHookshot && hitshield(wpnx, wpny, xdir))
5789
4/10
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 76 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 76 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 76 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 76 times.
76 || ((flags&inv_front && wpnDir==(xdir^down)) || (flags&inv_back && wpnDir==(xdir^up)) || (flags&inv_left && wpnDir==(xdir^left)) || (flags&inv_right && wpnDir==(xdir^right))))
5790 )
5791 // The hammer should already be dealt with by subclasses (Walker etc.)
5792 {
5793 switch(wpnId)
5794 {
5795 // Weapons which shields protect against
5796 case wSword:
5797 case wWand:
5798 if(Hero.getCharging()>0)
5799 Hero.setAttackClk(Hero.getAttackClk()+1); //Cancel charging
5800
5801 [[fallthrough]];
5802 case wHookshot:
5803 case wHSHandle:
5804 case wBrang:
5805 shieldCanBlock=true;
5806 break;
5807
5808 case wBeam:
5809 case wRefBeam:
5810 // Mirror shielded enemies!
5811 #if 0
5812 if(false /*flags2&guy_mirror*/ && !get_bit(quest_rules,qr_SWORDMIRROR))
5813 {
5814 if(wpnId>wEnemyWeapons)
5815 return 0;
5816
5817 sfx(WAV_CHINK,pan(int32_t(x)));
5818 return 1;
5819 }
5820
5821 #endif
5822
5823 [[fallthrough]];
5824 case wRefRock:
5825 case wRefFireball:
5826 case wMagic:
5827 #if 0
5828 if(false /*flags2&guy_mirror*/ && (wpnId!=wRefRock || get_bit(quest_rules,qr_REFLECTROCKS)))
5829 {
5830 sfx(WAV_CHINK,pan(int32_t(x)));
5831 return 3;
5832 }
5833
5834 #endif
5835
5836 if(wpnId>wEnemyWeapons)
5837 return 0;
5838
5839 [[fallthrough]];
5840 default:
5841 shieldCanBlock=true;
5842 break;
5843
5844 // Bombs
5845 case wSBomb:
5846 case wBomb:
5847 if (!get_bit(quest_rules,qr_TRUEFIXEDBOMBSHIELD)) goto hitclock;
5848 else if (!get_bit(quest_rules,qr_BOMBSPIERCESHIELD))
5849 {
5850 sfx(WAV_CHINK,pan(int32_t(x)));
5851 return 0;
5852 }
5853 else break;
5854
5855 // Weapons which ignore shields
5856 case wWhistle:
5857 case wHammer:
5858 break;
5859
5860 // Weapons which shouldn't be removed by shields
5861 case wLitBomb:
5862 case wLitSBomb:
5863 case wWind:
5864 case wPhantom:
5865 case wSSparkle:
5866 case wBait:
5867 return 0;
5868
5869 [[fallthrough]];
5870 case wFire:
5871 #if 0
5872 if(false /*flags2&guy_mirror*/)
5873 {
5874 sfx(WAV_CHINK,pan(int32_t(x)));
5875 return 1;
5876 }
5877
5878 #endif
5879 ;
5880 }
5881 }
5882
5883
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
76 switch(wpnId)
5884 {
5885 case wWhistle: //No longer completely ignore whistle weapons! -Z
5886 {
5887
5888 if ( ((itemsbuf[parent_item].flags & ITEM_FLAG2) == 0) || ( parent_item == -1 ) ) //if the flag is set, or the weapon is scripted
5889 {
5890 //al_trace("Whistle weapon in %s\n", "takehit flag == 0");
5891 return 0; break;
5892 }
5893 else
5894 {
5895 w->power = power = itemsbuf[parent_item].misc5;
5896
5897 int32_t def = defendNewInt(wpnId, &power, resolveEnemyDefence(w), w->unblockable, w);
5898
5899 if(def <= 0)
5900 {
5901 if ( def == -2 ) hp -= hp;
5902 else hp -= power;
5903 return def;
5904 }
5905 break;
5906 }
5907 break;
5908 }
5909
5910 case wPhantom:
5911 return 0;
5912
5913 case wLitBomb:
5914 case wLitSBomb:
5915 case wBait:
5916 case wWind:
5917 case wSSparkle:
5918 return 0;
5919
5920 case wFSparkle:
5921
5922 // Only take sparkle damage if the sparkle's parent item is not
5923 // defended against.
5924 if(enemyHitWeapon > -1)
5925 {
5926 int32_t p = 0;
5927 int32_t f = itemsbuf[enemyHitWeapon].family;
5928
5929 switch(f)
5930 {
5931 case itype_arrow:
5932 if(!candamage(p, edefARROW, w->unblockable)) return 0;
5933
5934 break;
5935
5936 case itype_cbyrna:
5937 if(!candamage(p, edefBYRNA, w->unblockable)) return 0;
5938
5939 break;
5940
5941 case itype_brang:
5942 if(!candamage(p, edefBRANG, w->unblockable)) return 0;
5943
5944 break;
5945
5946 default:
5947 return 0;
5948 }
5949 }
5950
5951 wpnId = wSword;
5952 power = game->get_hero_dmgmult()>>1;
5953 goto fsparkle;
5954 break;
5955
5956 case wBrang:
5957 {
5958 //int32_t def = defendNew(wpnId, &power, edefBRANG, w);
5959 int32_t def = defendNewInt(wpnId, &power, resolveEnemyDefence(w), w->unblockable, w);
5960 //preventing stunlock might be best, here. -Z
5961 if(def >= 0) return def;
5962
5963 // Not hurt by 0-damage weapons
5964 if(!(flags & guy_bhit))
5965 {
5966 stunclk=160;
5967
5968 if(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_brang))
5969 {
5970 hp -= (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_brang))*game->get_hero_dmgmult();
5971 goto hitclock;
5972 }
5973
5974 break;
5975 }
5976
5977 if(!power)
5978 hp-=(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].fam_type : current_item(itype_brang))*game->get_hero_dmgmult();
5979 else
5980 hp-=power;
5981
5982 goto hitclock;
5983 }
5984
5985 case wHookshot:
5986 {
5987 //int32_t def = defendNew(wpnId, &power, edefHOOKSHOT,w);
5988 int32_t def = defendNewInt(wpnId, &power, resolveEnemyDefence(w), w->unblockable, w);
5989
5990 if(def >= 0) return def;
5991
5992 bool swgrab = switch_hooked || w->family_class == itype_switchhook;
5993 if(swgrab || !(flags & guy_bhit))
5994 {
5995 if(!swgrab)
5996 stunclk=160;
5997
5998 if(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_hookshot))
5999 {
6000 hp -= (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_hookshot))*game->get_hero_dmgmult();
6001 goto hitclock;
6002 }
6003
6004 break;
6005 }
6006
6007 if(!power) hp-=(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].fam_type : current_item(itype_hookshot))*game->get_hero_dmgmult();
6008 else
6009 hp-=power;
6010
6011 goto hitclock;
6012 }
6013 break;
6014
6015 case wHSHandle:
6016 {
6017 if(itemsbuf[enemyHitWeapon>-1 ? enemyHitWeapon : current_item_id(itype_hookshot)].flags & ITEM_FLAG1)
6018 return 0;
6019
6020 bool ignorehookshot = ((defense[edefHOOKSHOT] == edIGNORE) || ((defense[edefHOOKSHOT] == edIGNOREL1 || defense[edefHOOKSHOT] == edSTUNORIGNORE)
6021 && (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_hookshot)) <= 0));
6022
6023 // Peahats, Darknuts, Aquamentuses, Pols Voices, Wizzrobes, Manhandlas
6024 if(!(family==eePEAHAT || family==eeAQUA || family==eeMANHAN || (family==eeWIZZ && !ignorehookshot)
6025 || (family==eeWALK && dmisc9==e9tPOLSVOICE) || (family==eeWALK && flags&(inv_back|inv_front|inv_left|inv_right))))
6026 return 0;
6027
6028 power = game->get_hero_dmgmult();
6029 }
6030
6031 fsparkle:
6032
6033 [[fallthrough]];
6034 default:
6035 // Work out the defenses!
6036 {
6037 76 int32_t def = defenditemclassNew(wpnId, &power, w);
6038
6039
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
76 if(def >= 0)
6040 return def;
6041
1/2
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
76 else if(def == -2)
6042 {
6043 ret = 0;
6044 }
6045 }
6046
6047
1/2
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
152 if(!power)
6048 {
6049 if(flags & guy_bhit)
6050 hp-=1;
6051 else
6052 {
6053 // Don't make a long chain of 'stun' hits
6054 if((wpnId==wFire || wpnId==wBomb || wpnId==wSBomb || wpnId==wSword) && stunclk>0)
6055 return 1;
6056
6057
6058 if(!switch_hooked)
6059 stunclk=160;
6060 break;
6061 }
6062 }
6063 76 else hp-=power;
6064
6065 hitclock:
6066 76 hclk=33;
6067
6068 // Use w->dir instead of wpnDir to make sure boomerangs don't push enemies the wrong way
6069
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 53 times.
76 if((dir&2)==(w->dir&2))
6070 {
6071 53 sclk=(w->dir<<8)+16;
6072 53 }
6073 76 }
6074
6075
2/6
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 76 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
76 if(((wpnId==wBrang) || (get_bit(quest_rules,qr_NOFLASHDEATH))) && (hp<=0 && !immortal))
6076 {
6077 fading=fade_blue_poof;
6078 }
6079
6080
6081 /*
6082 if( hitsfx > 0 ) //user set hit sound.
6083 {
6084 if ( !dying ) //Don't play the hit sound when dying.
6085 sfx(hitsfx, pan(int32_t(x)));
6086 }
6087 else sfx(WAV_EHIT, pan(int32_t(x))); //Don't play this one if the user sets a custom sound!
6088 */
6089 /*
6090 if( hitsfx > 0 ) //A sound is set.
6091 {
6092 if ( !dying ) //Don't play the hit sound when dying.
6093 sfx(hitsfx, pan(int32_t(x)));
6094 }
6095 */
6096
3/6
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 76 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 76 times.
✗ Branch 5 not taken.
76 if ( FFCore.getQuestHeaderInfo(vZelda) > 0x250 || ( FFCore.getQuestHeaderInfo(vZelda) == 0x250 && FFCore.getQuestHeaderInfo(vBuild) > 31 )) //2.53 Gamma 2 and later
6097 {
6098
1/2
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
76 if( hitsfx > 0 ) //user-set hit sound.
6099 {
6100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
76 if (!dying) //don't play the hit sound on death! -Z
6101 76 sfx(hitsfx, pan(int32_t(x)));
6102 76 }
6103 else sfx(WAV_EHIT, pan(int32_t(x))); //Don't play the hardcoded sound if the user sets a custom one.
6104 76 }
6105 else //2.50.2 or earlier
6106 {
6107 sfx(WAV_EHIT, pan(int32_t(x)));
6108 sfx(hitsfx, pan(int32_t(x)));
6109 }
6110
2/2
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 1 times.
76 if(family==eeGUY)
6111 1 sfx(WAV_EDEAD, pan(int32_t(x)));
6112
6113 // Penetrating weapons
6114
3/4
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 38 times.
76 if((wpnId==wArrow || wpnId==wBeam) && !cannotpenetrate())
6115 {
6116 38 int32_t item=enemyHitWeapon;
6117
6118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if(wpnId==wArrow)
6119 {
6120 //If we use an arrow type for the item's Weapon type, the flags differ, so we need to rely on the flags from an arrow class.
6121 if(item>=0 && (itemsbuf[item].flags&ITEM_FLAG1) && (itemsbuf[parent_item].family == itype_arrow))
6122 return 0;
6123 else if(get_bit(quest_rules,qr_ARROWS_ALWAYS_PENETRATE)) return 0;
6124 //if(item<0)
6125 else
6126 item=current_item_id(itype_arrow);
6127 }
6128
6129 else
6130 {
6131
6132 //If we use an swordbeam type for the item's Weapon type, the flags differ, so we need to rely on the flags from an arrow class.
6133
2/6
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 38 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
38 if(item>=0 && (itemsbuf[item].flags&ITEM_FLAG3) && (itemsbuf[parent_item].family == itype_sword))
6134 return 0;
6135
6136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 else if(get_bit(quest_rules,qr_SWORDBEAMS_ALWAYS_PENETRATE)) return 0;
6137 else
6138 //if(item<0)
6139 38 item=current_item_id(itype_sword);
6140 }
6141 38 }
6142
6143 76 return ret;
6144 76 }
6145
6146 52578 bool enemy::dont_draw()
6147 {
6148
3/6
✓ Branch 0 taken 52578 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52578 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 52578 times.
52578 if(fading==fade_invisible || (((flags2&guy_blinking)||(fading==fade_flicker)) && (clk&1)))
6149 return true;
6150
6151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52578 times.
52578 if(flags&guy_invisible)
6152 return true;
6153
6154
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 52578 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
52578 if(flags&lens_only && !lensclk)
6155 return true;
6156
6157
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 52578 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
52578 if(lensclk && (itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG6) && !(itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG7) &&
6158 !((flags&lens_only) && (get_bit(quest_rules,qr_LENSSEESENEMIES) || (itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG5))))
6159 return true;
6160
6161 52578 return false;
6162 52578 }
6163
6164 #define DRAW_NORMAL 2
6165 #define DRAW_CLOAKED 1
6166 #define DRAW_INVIS 0
6167 // base drawing function to be used by all derived classes instead of
6168 // sprite::draw()
6169 52656 void enemy::draw(BITMAP *dest)
6170 {
6171
3/6
✓ Branch 0 taken 52656 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52656 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 52656 times.
52656 if(fading==fade_invisible || (((flags2&guy_blinking)||(fading==fade_flicker)) && (clk&1)))
6172 return;
6173
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 52578 times.
52656 if(flags&guy_invisible)
6174 78 return;
6175
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 52578 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
52578 if(lensclk && (itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG6) && !(itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG7) && !(flags&lens_only))
6176 return;
6177
6178 //We did the normal don't_draw stuff here so we can make exceptions; specifically the lens check (which should make enemies
6179 // be cloaked if they have "invisible displays as cloaked" checked.
6180
6181 52578 byte canSee = DRAW_NORMAL;
6182 //Enemy specific stuff
6183
1/2
✓ Branch 0 taken 52578 times.
✗ Branch 1 not taken.
52578 if ( editorflags & ENEMY_FLAG1 )
6184 {
6185 canSee = DRAW_INVIS;
6186 if (editorflags & ENEMY_FLAG4) canSee = DRAW_CLOAKED;
6187 if (dmisc13 >= 0 && (editorflags & ENEMY_FLAG2))
6188 {
6189 if (game->item[dmisc13])
6190 {
6191 canSee = DRAW_NORMAL;
6192 }
6193 //else if ( lensclk && getlensid.flags SHOWINVIS )
6194 //{
6195 //
6196 //}
6197 //else
6198 //{
6199 // if ( (editorflags & ENEMY_FLAG4) ) canSee = DRAW_CLOAKED;
6200 // //otherwisem invisible
6201 //}
6202 }
6203 }
6204 //Room specific
6205
1/2
✓ Branch 0 taken 52578 times.
✗ Branch 1 not taken.
52578 if (tmpscr->flags3&fINVISROOM)
6206 {
6207 if (canSee == DRAW_NORMAL && !(current_item(itype_amulet)) &&
6208 !((itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG5) && lensclk) && family!=eeGANON) canSee = DRAW_CLOAKED;
6209 }
6210 //Lens check
6211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52578 times.
52578 if (lensclk)
6212 {
6213 if((itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG6) && !(flags&lens_only))
6214 {
6215 if (canSee == DRAW_NORMAL)
6216 {
6217 if (itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG7) canSee = DRAW_CLOAKED;
6218 else canSee = DRAW_INVIS; //Should never happen cause dont_draw should catch this, but just in case.
6219 }
6220 }
6221 if(flags&lens_only)
6222 {
6223 if (canSee == DRAW_INVIS) canSee = DRAW_NORMAL;
6224 }
6225 }
6226 else
6227 {
6228
1/2
✓ Branch 0 taken 52578 times.
✗ Branch 1 not taken.
52578 if(flags&lens_only)
6229 canSee = DRAW_INVIS;
6230 }
6231
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 52578 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
52578 if (canSee == DRAW_INVIS && (editorflags & ENEMY_FLAG4)) canSee = DRAW_CLOAKED;
6232
2/4
✓ Branch 0 taken 52578 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52578 times.
✗ Branch 3 not taken.
52578 if (canSee == DRAW_NORMAL && (editorflags & ENEMY_FLAG16)) canSee = DRAW_CLOAKED;
6233
6234
1/2
✓ Branch 0 taken 52578 times.
✗ Branch 1 not taken.
52578 if (canSee == DRAW_INVIS)
6235 return;
6236
6237
2/4
✓ Branch 0 taken 52578 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 52578 times.
52578 if(fallclk||drownclk)
6238 {
6239 if (canSee == DRAW_CLOAKED)
6240 {
6241 sprite::drawcloaked(dest);
6242 }
6243 else if (canSee == DRAW_NORMAL)
6244 {
6245 sprite::draw(dest);
6246 }
6247 return;
6248 }
6249 52578 int32_t cshold=cs;
6250
6251
2/2
✓ Branch 0 taken 946 times.
✓ Branch 1 taken 51632 times.
52578 if(dying)
6252 {
6253
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 946 times.
946 if(clk2>=19)
6254 {
6255 if(!(clk2&2))
6256 {
6257 //if the enemy isn't totally invisible, or if it is, but Hero has the item needed to reveal it, draw it.
6258 if (canSee == DRAW_CLOAKED)
6259 {
6260 sprite::drawcloaked(dest);
6261 }
6262 else if (canSee == DRAW_NORMAL)
6263 {
6264 sprite::draw(dest);
6265 }
6266 }
6267 return;
6268 }
6269
6270 946 flip = 0;
6271 946 tile = wpnsbuf[spr_death].tile;
6272
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 946 times.
946 if ( do_animation )
6273 {
6274 946 int32_t offs = 0;
6275
1/2
✓ Branch 0 taken 946 times.
✗ Branch 1 not taken.
946 if(!get_bit(quest_rules,qr_HARDCODED_ENEMY_ANIMS))
6276 {
6277 if(clk2 > 2)
6278 {
6279 spr_death_anim_clk=0;
6280 clk2=1;
6281 if(hp > -1000)
6282 death_sfx();
6283 }
6284 if(clk2==1 && spr_death_anim_clk>-1)
6285 {
6286 ++clk2;
6287 spr_death_anim_frm=(spr_death_anim_clk/zc_max(wpnsbuf[spr_death].speed,1));
6288 spr_death_anim_frm *= zc_max(1,txsz);
6289 int32_t rows = TILEROW(tile+spr_death_anim_frm)-TILEROW(tile);
6290 spr_death_anim_frm += TILES_PER_ROW*(zc_min(0,tysz-1)*rows);
6291 if(++spr_death_anim_clk >= (zc_max(wpnsbuf[spr_death].speed,1) * zc_max(wpnsbuf[spr_death].frames,1)))
6292 {
6293 spr_death_anim_clk=-1;
6294 clk2=1;
6295 }
6296 }
6297 tile += spr_death_anim_frm;
6298 }
6299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 946 times.
946 else if(BSZ)
6300 {
6301 offs = zc_min((15-clk2)/3,4);
6302 }
6303
4/4
✓ Branch 0 taken 634 times.
✓ Branch 1 taken 312 times.
✓ Branch 2 taken 322 times.
✓ Branch 3 taken 312 times.
946 else if(clk2>6 && clk2<=12)
6304 {
6305 312 offs = 1;
6306 312 }
6307
6308
2/2
✓ Branch 0 taken 634 times.
✓ Branch 1 taken 312 times.
946 if(offs)
6309 {
6310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 312 times.
312 offs *= zc_max(1,txsz);
6311 312 int32_t rows = TILEROW(tile+offs)-TILEROW(tile);
6312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 312 times.
312 offs += TILES_PER_ROW*(zc_min(0,tysz-1)*rows);
6313 312 }
6314 946 tile += offs;
6315 946 }
6316
6317
3/6
✓ Branch 0 taken 946 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 946 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 946 times.
946 if(!get_bit(quest_rules,qr_HARDCODED_ENEMY_ANIMS) || BSZ || fading==fade_blue_poof)
6318 cs = wpnsbuf[spr_death].csets&15;
6319 else
6320 946 cs = (((clk2+5)>>1)&3)+6;
6321 946 }
6322
3/4
✓ Branch 0 taken 1443 times.
✓ Branch 1 taken 50189 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1443 times.
51632 else if(hclk>0 && getCanFlicker())
6323 {
6324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1443 times.
1443 if(family==eeGANON)
6325 cs=(((hclk-1)>>1)&3)+6;
6326
3/4
✓ Branch 0 taken 1344 times.
✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1344 times.
1443 else if(hclk<33 && !get_bit(quest_rules,qr_ENEMIESFLICKER))
6327 1344 cs=(((hclk-1)>>1)&3)+6;
6328 1443 }
6329 //draw every other frame for flickering enemies
6330
6/10
✓ Branch 0 taken 26267 times.
✓ Branch 1 taken 26311 times.
✓ Branch 2 taken 26267 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1196 times.
✓ Branch 5 taken 25071 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1196 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
52578 if((frame&1)==1 || !(family !=eeGANON && hclk>0 && get_bit(quest_rules,qr_ENEMIESFLICKER) && getCanFlicker()))
6331 {
6332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52578 times.
52578 if (canSee == DRAW_CLOAKED)
6333 {
6334 sprite::drawcloaked(dest);
6335 }
6336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52578 times.
52578 else if (canSee == DRAW_NORMAL)
6337 {
6338
1/2
✓ Branch 0 taken 52578 times.
✗ Branch 1 not taken.
52578 if ( frozenclock < 0 )
6339 {
6340 if ( frozentile > 0 ) tile = frozentile;
6341 loadpalset(csBOSS,frozencset);
6342 }
6343 52578 sprite::draw(dest);
6344 52578 }
6345 52578 }
6346 52578 cs=cshold;
6347 52656 }
6348
6349 //old zc bosses
6350 28959 void enemy::drawzcboss(BITMAP *dest)
6351 {
6352
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28959 times.
28959 if(dont_draw())
6353 return;
6354
6355 28959 int32_t cshold=cs;
6356
6357
2/2
✓ Branch 0 taken 946 times.
✓ Branch 1 taken 28013 times.
28959 if(dying)
6358 {
6359
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 946 times.
946 if(clk2>=19)
6360 {
6361 if(!(clk2&2))
6362 sprite::drawzcboss(dest);
6363
6364 return;
6365 }
6366
6367 946 flip = 0;
6368 946 tile = wpnsbuf[spr_death].tile;
6369
6370
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 946 times.
946 if ( do_animation )
6371 {
6372
1/2
✓ Branch 0 taken 946 times.
✗ Branch 1 not taken.
946 if(!get_bit(quest_rules,qr_HARDCODED_ENEMY_ANIMS))
6373 {
6374 if(clk2 > 2)
6375 {
6376 spr_death_anim_clk=0;
6377 clk2=1;
6378 if(hp > -1000)
6379 death_sfx();
6380 }
6381 if(clk2==1 && spr_death_anim_clk>-1)
6382 {
6383 ++clk2;
6384 spr_death_anim_frm=(spr_death_anim_clk/zc_max(wpnsbuf[spr_death].speed,1));
6385 spr_death_anim_frm *= zc_max(1,txsz);
6386 int32_t rows = TILEROW(tile+spr_death_anim_frm)-TILEROW(tile);
6387 spr_death_anim_frm += TILES_PER_ROW*(zc_min(0,tysz-1)*rows);
6388 if(++spr_death_anim_clk >= (zc_max(wpnsbuf[spr_death].speed,1) * zc_max(wpnsbuf[spr_death].frames,1)))
6389 {
6390 spr_death_anim_clk=-1;
6391 clk2=1;
6392 }
6393 }
6394 tile += spr_death_anim_frm;
6395 }
6396
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 946 times.
946 else if(BSZ)
6397 tile += zc_min((15-clk2)/3,4);
6398
4/4
✓ Branch 0 taken 634 times.
✓ Branch 1 taken 312 times.
✓ Branch 2 taken 322 times.
✓ Branch 3 taken 312 times.
946 else if(clk2>6 && clk2<=12)
6399 312 ++tile;
6400 946 }
6401
6402
3/6
✓ Branch 0 taken 946 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 946 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 946 times.
946 if(!get_bit(quest_rules,qr_HARDCODED_ENEMY_ANIMS) || BSZ || fading==fade_blue_poof)
6403 cs = wpnsbuf[spr_death].csets&15;
6404 else
6405 946 cs = (((clk2+5)>>1)&3)+6;
6406 946 }
6407
2/2
✓ Branch 0 taken 26570 times.
✓ Branch 1 taken 1443 times.
28013 else if(hclk>0)
6408 {
6409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1443 times.
1443 if(family==eeGANON)
6410 cs=(((hclk-1)>>1)&3)+6;
6411
3/4
✓ Branch 0 taken 1344 times.
✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1344 times.
1443 else if(hclk<33 && !get_bit(quest_rules,qr_ENEMIESFLICKER))
6412 1344 cs=(((hclk-1)>>1)&3)+6;
6413 1443 }
6414
6415
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 28959 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
28959 if((tmpscr->flags3&fINVISROOM) &&
6416 !(current_item(itype_amulet)) &&
6417 !(get_bit(quest_rules,qr_LENSSEESENEMIES) &&
6418 lensclk) && family!=eeGANON)
6419 {
6420 sprite::drawcloaked(dest);
6421 }
6422 else
6423 {
6424
4/6
✓ Branch 0 taken 28959 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2389 times.
✓ Branch 3 taken 26570 times.
✓ Branch 4 taken 2389 times.
✗ Branch 5 not taken.
28959 if(family !=eeGANON && hclk>0 && get_bit(quest_rules,qr_ENEMIESFLICKER))
6425 {
6426 if((frame&1)==1)
6427 sprite::drawzcboss(dest);
6428 }
6429 else
6430 28959 sprite::drawzcboss(dest);
6431 }
6432
6433 28959 cs=cshold;
6434 28959 }
6435
6436
6437 // similar to the overblock function--can do up to a 32x32 sprite
6438 //will this play nicely with scripttile, solely using the modifications in sprite::draw()?
6439 void enemy::drawblock(BITMAP *dest,int32_t mask)
6440 {
6441 int32_t thold=tile;
6442 int32_t t1=tile;
6443 int32_t t2=tile+20;
6444 int32_t t3=tile+1;
6445 int32_t t4=tile+21;
6446
6447 switch(mask)
6448 {
6449 case 1:
6450 enemy::drawzcboss(dest);
6451 break;
6452
6453 case 3:
6454 if(flip&2)
6455 zc_swap(t1,t2);
6456
6457 tile=t1;
6458 enemy::drawzcboss(dest);
6459 tile=t2;
6460 yofs+=16;
6461 enemy::drawzcboss(dest);
6462 yofs-=16;
6463 break;
6464
6465 case 5:
6466 t2=tile+1;
6467
6468 if(flip&1)
6469 zc_swap(t1,t2);
6470
6471 tile=t1;
6472 enemy::drawzcboss(dest);
6473 tile=t2;
6474 xofs+=16;
6475 enemy::drawzcboss(dest);
6476 xofs-=16;
6477 break;
6478
6479 case 15:
6480 if(flip&1)
6481 {
6482 zc_swap(t1,t3);
6483 zc_swap(t2,t4);
6484 }
6485
6486 if(flip&2)
6487 {
6488 zc_swap(t1,t2);
6489 zc_swap(t3,t4);
6490 }
6491
6492 tile=t1;
6493 enemy::drawzcboss(dest);
6494 tile=t2;
6495 yofs+=16;
6496 enemy::drawzcboss(dest);
6497 yofs-=16;
6498 tile=t3;
6499 xofs+=16;
6500 enemy::drawzcboss(dest);
6501 tile=t4;
6502 yofs+=16;
6503 enemy::drawzcboss(dest);
6504 xofs-=16;
6505 yofs-=16;
6506 break;
6507 }
6508
6509 tile=thold;
6510 }
6511
6512 23619 void enemy::drawshadow(BITMAP *dest, bool translucent)
6513 {
6514
3/4
✓ Branch 0 taken 23619 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6730 times.
✓ Branch 3 taken 16889 times.
23619 if(dont_draw() || isSideViewGravity())
6515 {
6516 6730 return;
6517 }
6518
6519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16889 times.
16889 if(dying)
6520 {
6521 return;
6522 }
6523
6524
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 16889 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16889 times.
16889 if(((tmpscr->flags3&fINVISROOM)&& !(current_item(itype_amulet)))||
6525 16889 (darkroom))
6526 {
6527 return;
6528 }
6529 else
6530 {
6531
3/4
✓ Branch 0 taken 16889 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16860 times.
✓ Branch 3 taken 29 times.
16889 if(enemycanfall(id, false) && shadowtile == 0)
6532 29 shadowtile = wpnsbuf[spr_shadow].tile;
6533
6534
3/6
✓ Branch 0 taken 16889 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16889 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16889 times.
✗ Branch 5 not taken.
16889 if(z>0 || fakez>0 || !enemycanfall(id, false))
6535 {
6536 if(!shadow_overpit(this))
6537 sprite::drawshadow(dest,translucent);
6538 }
6539 }
6540 23619 }
6541
6542 920 void enemy::masked_draw(BITMAP *dest,int32_t mx,int32_t my,int32_t mw,int32_t mh)
6543 {
6544 920 BITMAP *sub=create_sub_bitmap(dest,mx,my,mw,mh);
6545
6546
1/2
✓ Branch 0 taken 920 times.
✗ Branch 1 not taken.
920 if(sub!=NULL)
6547 {
6548 920 xofs-=mx;
6549 920 yofs-=my;
6550 920 enemy::draw(sub);
6551 920 xofs+=mx;
6552 920 yofs+=my;
6553 920 destroy_bitmap(sub);
6554 920 }
6555 else
6556 enemy::draw(dest);
6557 920 }
6558
6559 // override hit detection to check for invicibility, stunned, etc
6560 bool enemy::hit(sprite *s)
6561 {
6562 if(!(s->scriptcoldet&1) || s->fallclk || s->drownclk) return false;
6563
6564 return (dying || hclk>0) ? false : sprite::hit(s);
6565 }
6566
6567 50804 bool enemy::hit(int32_t tx,int32_t ty,int32_t tz,int32_t txsz2,int32_t tysz2,int32_t tzsz2)
6568 {
6569
4/4
✓ Branch 0 taken 49744 times.
✓ Branch 1 taken 1060 times.
✓ Branch 2 taken 48663 times.
✓ Branch 3 taken 1081 times.
50804 return (dying || hclk>0) ? false : sprite::hit(tx,ty,tz,txsz2,tysz2,tzsz2);
6570 }
6571 bool enemy::hit(int32_t tx,int32_t ty,int32_t txsz2,int32_t tysz2)
6572 {
6573 return (dying || hclk>0) ? false : sprite::hit(tx,ty,txsz2,tysz2);
6574 }
6575
6576 3128 bool enemy::hit(weapon *w)
6577 {
6578
3/6
✓ Branch 0 taken 3128 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3128 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3128 times.
3128 if(!(w->scriptcoldet&1) || w->fallclk || w->drownclk) return false;
6579
6580
4/4
✓ Branch 0 taken 3068 times.
✓ Branch 1 taken 60 times.
✓ Branch 2 taken 2976 times.
✓ Branch 3 taken 92 times.
3128 return (dying || hclk>0) ? false : sprite::hit(w);
6581 3128 }
6582
6583 30586 bool enemy::can_pitfall(bool checkspawning)
6584 {
6585
3/4
✓ Branch 0 taken 30586 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29716 times.
✓ Branch 3 taken 870 times.
30586 if((fading||isspawning)&&checkspawning) return false; //Don't fall during spawn.
6586
2/2
✓ Branch 0 taken 29701 times.
✓ Branch 1 taken 15 times.
29716 switch(guysbuf[id&0xFFF].family)
6587 {
6588 case eeAQUA:
6589 case eeDIG:
6590 case eeDONGO:
6591 case eeFAIRY:
6592 case eeGANON:
6593 case eeGHOMA:
6594 case eeGLEEOK:
6595 case eeGUY:
6596 case eeLANM:
6597 case eeMANHAN:
6598 case eeMOLD:
6599 case eeNONE:
6600 case eePATRA:
6601 case eeZORA:
6602 15 return false; //Disallowed types
6603 default:
6604 29701 return true;
6605 }
6606 30586 }
6607 //Handle death
6608 52054 void enemy::try_death(bool force_kill)
6609 {
6610
5/8
✓ Branch 0 taken 52054 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52054 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49 times.
✓ Branch 5 taken 52005 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 49 times.
52054 if(!dying && (force_kill || (hp<=0 && !immortal)))
6611 {
6612 49 std::vector<int32_t> &ev = FFCore.eventData;
6613 49 ev.clear();
6614 49 ev.push_back(10000);
6615 49 ev.push_back(getUID());
6616
6617 49 throwGenScriptEvent(GENSCR_EVENT_ENEMY_DEATH);
6618 49 bool isSaved = !ev[0];
6619 49 ev.clear();
6620
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
49 if(isSaved) return;
6621
6622
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
49 if(itemguy && (hasitem&2)!=0)
6623 {
6624
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for(int32_t i=0; i<items.Count(); i++)
6625 {
6626
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(((item*)items.spr(i))->pickup&ipENEMY)
6627 {
6628
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!get_bit(quest_rules, qr_BROKEN_ITEM_CARRYING))
6629 {
6630 if (get_bit(quest_rules, qr_ENEMY_DROPS_USE_HITOFFSETS))
6631 {
6632 items.spr(i)->x = x+hxofs+(hxsz/2)-8;
6633 items.spr(i)->y = y+hyofs+(hysz/2)-10-fakez;
6634 }
6635 else
6636 {
6637 if(extend >= 3)
6638 {
6639 items.spr(i)->x = x+(txsz-1)*8;
6640 items.spr(i)->y = y-2+(tysz-1)*8;
6641 }
6642 else
6643 {
6644 items.spr(i)->x = x;
6645 items.spr(i)->y = y - 2;
6646 }
6647 }
6648 items.spr(i)->z = z;
6649 items.spr(i)->fakez = fakez;
6650 }
6651 else
6652 {
6653 1 items.spr(i)->x = x;
6654 1 items.spr(i)->y = y - 2;
6655 }
6656 1 }
6657 1 }
6658 1 }
6659
6660 49 dying=true;
6661
6662
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
49 if(fading==fade_flash_die)
6663 clk2=19+18*4;
6664 else
6665 {
6666 49 clk2 = BSZ ? 15 : 19;
6667
6668
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
49 if(fading!=fade_blue_poof)
6669 49 fading=0;
6670 }
6671
6672
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 1 times.
49 if(itemguy)
6673 {
6674 1 hasitem&=~2;
6675 1 item_set=0;
6676 1 }
6677
6678
3/6
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 49 times.
49 if(currscr<128 && count_enemy && !script_spawned)
6679 49 game->guys[(currmap<<7)+currscr]-=1;
6680 49 }
6681 52054 }
6682
6683 // --==**==--
6684
6685 // Movement routines that can be used by derived classes as needed
6686
6687 // --==**==--
6688
6689 1291 void enemy::fix_coords(bool bound)
6690 {
6691
1/2
✓ Branch 0 taken 1291 times.
✗ Branch 1 not taken.
1291 if ((get_bit(quest_rules,qr_OUTOFBOUNDSENEMIES) ? 1 : 0) ^ ((editorflags&ENEMY_FLAG11)?1:0)) return;
6692
1/2
✓ Branch 0 taken 1291 times.
✗ Branch 1 not taken.
1291 if(moveflags & FLAG_IGNORE_SCREENEDGE) bound = false;
6693
6694
6695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1291 times.
1291 if(bound)
6696 {
6697
1/2
✓ Branch 0 taken 1291 times.
✗ Branch 1 not taken.
1291 if ( ((unsigned)(id&0xFFF)) < MAXGUYS )
6698 {
6699
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1291 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1291 x=vbound(x, 0, (( guysbuf[id].SIZEflags&guyflagOVERRIDE_TILE_WIDTH && !isflier(id) ) ? (256-((txsz-1)*16)) : 240));
6700
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1291 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1291 y=vbound(y, 0,(( guysbuf[id].SIZEflags&guyflagOVERRIDE_TILE_HEIGHT && !isflier(id) ) ? (176-((txsz-1)*16)) : 160));
6701 1291 }
6702 else
6703 {
6704 x=vbound(x, 0,240);
6705 y=vbound(y, 0,160);
6706 }
6707 1291 }
6708
6709
6/10
✓ Branch 0 taken 1021 times.
✓ Branch 1 taken 270 times.
✓ Branch 2 taken 1291 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1291 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1291 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1291 times.
1291 if(!OUTOFBOUNDS)
6710 {
6711 /*x=((int32_t(x)&0xF0)+((int32_t(x)&8)?16:0));
6712
6713 if(isSideViewGravity())
6714 y=((int32_t(y)&0xF8)+((int32_t(y)&4)?8:0));
6715 else
6716 y=((int32_t(y)&0xF0)+((int32_t(y)&8)?16:0));
6717 */
6718 1291 do_fix(x, 16, true);
6719
2/2
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 1021 times.
1291 if(isSideViewGravity())
6720 270 do_fix(y,8,true);
6721 1021 else do_fix(y,16,true);
6722 1291 }
6723 1291 }
6724 44 bool enemy::cannotpenetrate()
6725 {
6726
3/4
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 38 times.
44 return (family == eeAQUA || family == eeMANHAN || family == eeGHOMA);
6727 }
6728
6729 bool enemy::canmove_old(int32_t ndir,zfix s,int32_t special,int32_t dx1,int32_t dy1,int32_t dx2,int32_t dy2)
6730 {
6731 bool ok;
6732 int32_t dx = 0, dy = 0;
6733 int32_t sv = 8;
6734
6735 //Why is this here??? Why is it needed???
6736 s += 0.5; // Make the ints round; doesn't seem to cause any problems.
6737
6738 switch(ndir)
6739 {
6740 case 8:
6741 case up:
6742 if(canfall(id) && isSideViewGravity())
6743 return false;
6744
6745 dy = dy1-s;
6746 special = (special==spw_clipbottomright)?spw_none:special;
6747 ok = !m_walkflag_old(x,y+dy,special, x, y) && !flyerblocked(x,y+dy, special);
6748 break;
6749
6750 case 12:
6751 case down:
6752 if(canfall(id) && isSideViewGravity())
6753 return false;
6754
6755 dy = dy2+s;
6756 ok = !m_walkflag_old(x,y+dy,special, x, y) && !flyerblocked(x,y+dy, special);
6757 break;
6758
6759 case 14:
6760 case left:
6761 dx = dx1-s;
6762 sv = ((isSideViewGravity())?7:8);
6763 special = (special==spw_clipbottomright||special==spw_clipright)?spw_none:special;
6764 ok = !m_walkflag_old(x+dx,y+sv,special, x, y) && !flyerblocked(x+dx,y+8, special);
6765 break;
6766
6767 case 10:
6768 case right:
6769 dx = dx2+s;
6770 sv = ((isSideViewGravity())?7:8);
6771 ok = !m_walkflag_old(x+dx,y+sv,special, x, y) && !flyerblocked(x+dx,y+8, special);
6772 break;
6773
6774 case 9:
6775 case r_up:
6776 dx = dx2+s;
6777 dy = dy1-s;
6778 ok = !m_walkflag_old(x,y+dy,special, x, y) && !m_walkflag_old(x+dx,y+sv,special, x, y) &&
6779 !flyerblocked(x,y+dy, special) && !flyerblocked(x+dx,y+8, special);
6780 break;
6781
6782 case 11:
6783 case r_down:
6784 dx = dx2+s;
6785 dx = dy2+s;
6786 ok = !m_walkflag_old(x,y+dy,special, x, y) && !m_walkflag_old(x+dx,y+sv,special, x, y) &&
6787 !flyerblocked(x,y+dy, special) && !flyerblocked(x+dx,y+8, special);
6788 break;
6789
6790 case 13:
6791 case l_down:
6792 dx = dx1-s;
6793 dy = dy2+s;
6794 ok = !m_walkflag_old(x,y+dy,special, x, y) && !m_walkflag_old(x+dx,y+sv,special, x, y) &&
6795 !flyerblocked(x,y+dy, special) && !flyerblocked(x+dx,y+8, special);
6796 break;
6797
6798 case 15:
6799 case l_up:
6800 dx = dx1-s;
6801 dy = dy1-s;
6802 ok = !m_walkflag_old(x,y+dy,special, x, y) && !m_walkflag_old(x+dx,y+sv,special, x, y) &&
6803 !flyerblocked(x,y+dy, special) && !flyerblocked(x+dx,y+8, special);
6804 break;
6805
6806 default:
6807 db=99;
6808 return true;
6809 }
6810
6811 return ok;
6812 }
6813
6814
6815
6816
6817 // returns true if next step is ok, false if there is something there
6818 4443 bool enemy::canmove(int32_t ndir,zfix s,int32_t special,int32_t dx1,int32_t dy1,int32_t dx2,int32_t dy2, bool kb)
6819 {
6820 4443 bool ok = false; //initialise the var, son't just declare it
6821 4443 int32_t dx = 0, dy = 0;
6822 4443 int32_t sv = 8;
6823 4443 int32_t tries = 2; int32_t try_x = 0; int32_t try_y = 0;
6824 //Why is this here??? Why is it needed???
6825 4443 s += 0.5; // Make the ints round; doesn't seem to cause any problems.
6826
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4443 times.
4443 int32_t usexoffs = (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) ? hxofs : 0;
6827
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4443 times.
4443 int32_t useyoffs = (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) ? hyofs : 0;
6828
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4443 times.
4443 int32_t usewid = (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) ? hxsz : 16;
6829
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4443 times.
4443 int32_t usehei = (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) ? hysz : 16;
6830 4443 bool offgrid = OFFGRID_ENEMY;
6831
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4443 times.
4443 if(!offgrid)
6832 {
6833 //Enemies smaller than 1-tile must act as 1-tile large, if off-grid movement is disabled.
6834
1/2
✓ Branch 0 taken 4443 times.
✗ Branch 1 not taken.
4443 if(usehei<16)usehei=16;
6835
1/2
✓ Branch 0 taken 4443 times.
✗ Branch 1 not taken.
4443 if(usewid<16)usewid=16;
6836 4443 }
6837
8/9
✓ Branch 0 taken 705 times.
✓ Branch 1 taken 804 times.
✓ Branch 2 taken 876 times.
✓ Branch 3 taken 914 times.
✓ Branch 4 taken 139 times.
✓ Branch 5 taken 560 times.
✓ Branch 6 taken 402 times.
✓ Branch 7 taken 43 times.
✗ Branch 8 not taken.
4443 switch(ndir) //need to check every 8 pixels between two points
6838 {
6839 case 8:
6840 case up:
6841 {
6842
4/4
✓ Branch 0 taken 520 times.
✓ Branch 1 taken 185 times.
✓ Branch 2 taken 444 times.
✓ Branch 3 taken 76 times.
705 if(enemycanfall(id) && isSideViewGravity())
6843 76 return false;
6844
6845 629 dy = dy1-s;
6846
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 629 times.
629 special = (special==spw_clipbottomright)?spw_none:special;
6847 629 tries = usewid/(offgrid ? 8 : 16);
6848 //Z_eventlog("Trying move UP, dy=%d,usewid=%d,usehei=%d\n",int32_t(dy),usewid,usehei);
6849
2/2
✓ Branch 0 taken 425 times.
✓ Branch 1 taken 629 times.
1054 for ( ; tries > 0; --tries )
6850 {
6851
2/2
✓ Branch 0 taken 204 times.
✓ Branch 1 taken 425 times.
629 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy,special, ndir, x+usexoffs+try_x, y+useyoffs, kb) && !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy, special,kb);
6852 629 try_x += (offgrid ? 8 : 16);
6853
2/2
✓ Branch 0 taken 425 times.
✓ Branch 1 taken 204 times.
629 if (!ok) break;
6854 425 }
6855
2/2
✓ Branch 0 taken 425 times.
✓ Branch 1 taken 204 times.
629 if(!ok) break;
6856
1/2
✓ Branch 0 taken 425 times.
✗ Branch 1 not taken.
425 if((usewid%16)>0) //Uneven width
6857 {
6858 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy,special, ndir, x+usexoffs+usewid-1, y+useyoffs, kb) && !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy, special,kb);
6859 }
6860 425 break;
6861 }
6862 case 12:
6863 case down:
6864 {
6865
4/4
✓ Branch 0 taken 481 times.
✓ Branch 1 taken 323 times.
✓ Branch 2 taken 425 times.
✓ Branch 3 taken 56 times.
804 if(enemycanfall(id) && isSideViewGravity())
6866 56 return false;
6867
6868 748 dy = dy2+s;
6869 748 tries = usewid/(offgrid ? 8 : 16);
6870 //Z_eventlog("Trying move DOWN, dy=%d,usewid=%d,usehei=%d\n",int32_t(dy),usewid,usehei);
6871
2/2
✓ Branch 0 taken 575 times.
✓ Branch 1 taken 748 times.
1323 for ( ; tries > 0; --tries )
6872 {
6873
3/4
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 575 times.
✓ Branch 2 taken 575 times.
✗ Branch 3 not taken.
748 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy,special, ndir, x+usexoffs+try_x, y+useyoffs, kb) && !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+zc_max(usehei-16,0), special,kb);
6874 748 try_x += (offgrid ? 8 : 16);
6875
2/2
✓ Branch 0 taken 575 times.
✓ Branch 1 taken 173 times.
748 if (!ok) break;
6876 575 }
6877
2/2
✓ Branch 0 taken 575 times.
✓ Branch 1 taken 173 times.
748 if(!ok) break;
6878
1/2
✓ Branch 0 taken 575 times.
✗ Branch 1 not taken.
575 if((usewid%16)>0) //Uneven width
6879 {
6880 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy,special, ndir, x+usexoffs+usewid-1, y+useyoffs, kb) && !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+zc_max(usehei-16,0), special,kb);
6881 }
6882 575 break;
6883 }
6884 case 14:
6885 case left:
6886 {
6887 876 dx = dx1-s;
6888 876 sv = ((isSideViewGravity())?7:0);
6889
2/4
✓ Branch 0 taken 876 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 876 times.
876 special = (special==spw_clipbottomright||special==spw_clipright)?spw_none:special;
6890 876 tries = usehei/(offgrid ? 8 : 16);
6891 //Z_eventlog("Trying move LEFT, dx=%d,usewid=%d,usehei=%d\n",int32_t(dx),usewid,usehei);
6892
2/2
✓ Branch 0 taken 656 times.
✓ Branch 1 taken 876 times.
1532 for ( ; tries > 0; --tries )
6893 {
6894
2/2
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 656 times.
876 ok = !m_walkflag(x+usexoffs+dx,y+useyoffs+try_y+sv,special, ndir, x+usexoffs, y+useyoffs+try_y, kb) && !flyerblocked(x+usexoffs+dx,y+8+useyoffs+try_y, special,kb);
6895 876 try_y += (offgrid ? 8 : 16);
6896
2/2
✓ Branch 0 taken 656 times.
✓ Branch 1 taken 220 times.
876 if (!ok) break;
6897 656 }
6898
2/2
✓ Branch 0 taken 656 times.
✓ Branch 1 taken 220 times.
876 if(!ok) break;
6899
1/2
✓ Branch 0 taken 656 times.
✗ Branch 1 not taken.
656 if((usehei%16)>0) //Uneven height
6900 {
6901 ok = !m_walkflag(x+usexoffs+dx,y+useyoffs+usehei-1+sv,special, ndir, x+usexoffs, y+useyoffs+usehei-1, kb) && !flyerblocked(x+usexoffs+dx,y+8+useyoffs+usehei-1, special,kb);
6902 }
6903 656 break;
6904 }
6905 case 10:
6906 case right:
6907 {
6908 914 dx = dx2+s;
6909 914 sv = ((isSideViewGravity())?7:0);
6910 914 tries = usehei/(offgrid ? 8 : 16);
6911 //Z_eventlog("Trying move RIGHT, dx=%d,usewid=%d,usehei=%d\n",int32_t(dx),usewid,usehei);
6912
2/2
✓ Branch 0 taken 608 times.
✓ Branch 1 taken 914 times.
1522 for ( ; tries > 0; --tries )
6913 {
6914
3/4
✓ Branch 0 taken 306 times.
✓ Branch 1 taken 608 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 608 times.
914 ok = !m_walkflag(x+usexoffs+dx,y+useyoffs+try_y+sv,special, ndir, x+usexoffs, y+useyoffs+try_y, kb) && !flyerblocked(x+usexoffs+dx+zc_max(usewid-16,0),y+8+useyoffs+try_y, special,kb);
6915 914 try_y += (offgrid ? 8 : 16);
6916
2/2
✓ Branch 0 taken 608 times.
✓ Branch 1 taken 306 times.
914 if (!ok) break;
6917 608 }
6918
2/2
✓ Branch 0 taken 608 times.
✓ Branch 1 taken 306 times.
914 if(!ok) break;
6919
1/2
✓ Branch 0 taken 608 times.
✗ Branch 1 not taken.
608 if((usehei%16)>0) //Uneven height
6920 {
6921 ok = !m_walkflag(x+usexoffs+dx,y+useyoffs+usehei-1+sv,special, ndir, x+usexoffs, y+useyoffs+usehei-1, kb) && !flyerblocked(x+usexoffs+dx+zc_max(usewid-16,0),y+8+useyoffs+usehei-1, special,kb);
6922 }
6923 608 break;
6924 }
6925 case 9:
6926 case r_up:
6927 {
6928 139 dx = dx2+s;
6929 139 dy = dy1-s;
6930 139 int32_t tries_x = usewid/(offgrid ? 8 : 16);
6931 139 sv = ((isSideViewGravity())?7:0);
6932
2/2
✓ Branch 0 taken 133 times.
✓ Branch 1 taken 139 times.
272 for ( ; tries_x > 0; --tries_x )
6933 {
6934 139 int32_t tries_y = usehei/(offgrid ? 8 : 16);
6935 139 try_y = 0;
6936
2/2
✓ Branch 0 taken 133 times.
✓ Branch 1 taken 139 times.
272 for ( ; tries_y > 0; --tries_y )
6937 {
6938
4/4
✓ Branch 0 taken 135 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 133 times.
✓ Branch 3 taken 2 times.
272 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) &&
6939
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 133 times.
133 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+try_y, special,kb);
6940 139 try_y += (offgrid ? 8 : 16);
6941
2/2
✓ Branch 0 taken 133 times.
✓ Branch 1 taken 6 times.
139 if (!ok) break;
6942 133 }
6943
2/2
✓ Branch 0 taken 133 times.
✓ Branch 1 taken 6 times.
139 if (!ok) break;
6944
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 133 times.
133 if((usehei%16)>0) //Uneven height
6945 {
6946 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) &&
6947 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+usehei-1, special,kb);
6948 }
6949 133 try_x += (offgrid ? 8 : 16);
6950 133 }
6951
2/2
✓ Branch 0 taken 133 times.
✓ Branch 1 taken 6 times.
139 if(!ok) break;
6952
1/2
✓ Branch 0 taken 133 times.
✗ Branch 1 not taken.
133 if((usewid%16)>0) //Uneven width
6953 {
6954 int32_t tries_y = usehei/(offgrid ? 8 : 16);
6955 try_y = 0;
6956 for ( ; tries_y > 0; --tries_y )
6957 {
6958 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) &&
6959 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+try_y, special,kb);
6960 try_y += (offgrid ? 8 : 16);
6961 if (!ok) break;
6962 }
6963 if (!ok) break;
6964 if((usehei%16)>0) //Uneven height
6965 {
6966 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) &&
6967 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+usehei-1, special,kb);
6968 }
6969 }
6970 133 break;
6971 }
6972 case 11:
6973 case r_down:
6974 {
6975 560 dx = dx2+s;
6976 560 dx = dy2+s;
6977 560 int32_t tries_x = usewid/(offgrid ? 8 : 16);
6978 //sv = ((isSideViewGravity())?7:0);
6979
2/2
✓ Branch 0 taken 554 times.
✓ Branch 1 taken 560 times.
1114 for ( ; tries_x > 0; --tries_x )
6980 {
6981 560 int32_t tries_y = usehei/(offgrid ? 8 : 16);
6982 560 try_y = 0;
6983
2/2
✓ Branch 0 taken 554 times.
✓ Branch 1 taken 560 times.
1114 for ( ; tries_y > 0; --tries_y )
6984 {
6985
3/4
✓ Branch 0 taken 560 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 554 times.
✓ Branch 3 taken 6 times.
1114 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) &&
6986
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 554 times.
554 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+try_y, special,kb);
6987 560 try_y += (offgrid ? 8 : 16);
6988
2/2
✓ Branch 0 taken 554 times.
✓ Branch 1 taken 6 times.
560 if (!ok) break;
6989 554 }
6990
2/2
✓ Branch 0 taken 554 times.
✓ Branch 1 taken 6 times.
560 if (!ok) break;
6991
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 554 times.
554 if((usehei%16)>0) //Uneven height
6992 {
6993 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) &&
6994 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+usehei-1, special,kb);
6995 }
6996 554 try_x += (offgrid ? 8 : 16);
6997 554 }
6998
2/2
✓ Branch 0 taken 554 times.
✓ Branch 1 taken 6 times.
560 if(!ok) break;
6999
1/2
✓ Branch 0 taken 554 times.
✗ Branch 1 not taken.
554 if((usewid%16)>0) //Uneven width
7000 {
7001 int32_t tries_y = usehei/(offgrid ? 8 : 16);
7002 try_y = 0;
7003 for ( ; tries_y > 0; --tries_y )
7004 {
7005 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) &&
7006 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+try_y, special,kb);
7007 try_y += (offgrid ? 8 : 16);
7008 if (!ok) break;
7009 }
7010 if (!ok) break;
7011 if((usehei%16)>0) //Uneven height
7012 {
7013 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) &&
7014 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+usehei-1, special,kb);
7015 }
7016 }
7017 554 break;
7018 }
7019 case 13:
7020 case l_down:
7021 {
7022 402 dx = dx1-s;
7023 402 dy = dy2+s;
7024 402 int32_t tries_x = usewid/(offgrid ? 8 : 16);
7025 //sv = ((isSideViewGravity())?7:0);
7026
2/2
✓ Branch 0 taken 398 times.
✓ Branch 1 taken 402 times.
800 for ( ; tries_x > 0; --tries_x )
7027 {
7028 402 int32_t tries_y = usehei/(offgrid ? 8 : 16);
7029 402 try_y = 0;
7030
2/2
✓ Branch 0 taken 398 times.
✓ Branch 1 taken 402 times.
800 for ( ; tries_y > 0; --tries_y )
7031 {
7032
3/4
✓ Branch 0 taken 398 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 398 times.
✗ Branch 3 not taken.
800 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) &&
7033
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 398 times.
398 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+try_y, special,kb);
7034 402 try_y += (offgrid ? 8 : 16);
7035
2/2
✓ Branch 0 taken 398 times.
✓ Branch 1 taken 4 times.
402 if (!ok) break;
7036 398 }
7037
2/2
✓ Branch 0 taken 398 times.
✓ Branch 1 taken 4 times.
402 if (!ok) break;
7038
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 398 times.
398 if((usehei%16)>0) //Uneven height
7039 {
7040 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) &&
7041 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+usehei-1, special,kb);
7042 }
7043 398 try_x += (offgrid ? 8 : 16);
7044 398 }
7045
2/2
✓ Branch 0 taken 398 times.
✓ Branch 1 taken 4 times.
402 if(!ok) break;
7046
1/2
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
398 if((usewid%16)>0) //Uneven width
7047 {
7048 int32_t tries_y = usehei/(offgrid ? 8 : 16);
7049 try_y = 0;
7050 for ( ; tries_y > 0; --tries_y )
7051 {
7052 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) &&
7053 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+try_y, special,kb);
7054 try_y += (offgrid ? 8 : 16);
7055 if (!ok) break;
7056 }
7057 if (!ok) break;
7058 if((usehei%16)>0) //Uneven height
7059 {
7060 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) &&
7061 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+usehei-1, special,kb);
7062 }
7063 }
7064 398 break;
7065 }
7066 case 15:
7067 case l_up:
7068 {
7069 43 dx = dx1-s;
7070 43 dy = dy1-s;
7071 43 int32_t tries_x = usewid/(offgrid ? 8 : 16);
7072 43 sv = ((isSideViewGravity())?7:0);
7073
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 43 times.
85 for ( ; tries_x > 0; --tries_x )
7074 {
7075 43 int32_t tries_y = usehei/(offgrid ? 8 : 16);
7076 43 try_y = 0;
7077
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 43 times.
85 for ( ; tries_y > 0; --tries_y )
7078 {
7079
3/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 42 times.
✗ Branch 3 not taken.
85 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) &&
7080
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+try_y, special,kb);
7081 43 try_y += (offgrid ? 8 : 16);
7082
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 1 times.
43 if (!ok) break;
7083 42 }
7084
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 1 times.
43 if (!ok) break;
7085
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if((usehei%16)>0) //Uneven height
7086 {
7087 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) &&
7088 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+usehei-1, special,kb);
7089 }
7090 42 try_x += (offgrid ? 8 : 16);
7091 42 }
7092
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 1 times.
43 if(!ok) break;
7093
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 if((usewid%16)>0) //Uneven width
7094 {
7095 int32_t tries_y = usehei/(offgrid ? 8 : 16);
7096 try_y = 0;
7097 for ( ; tries_y > 0; --tries_y )
7098 {
7099 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) &&
7100 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+try_y, special,kb);
7101 try_y += (offgrid ? 8 : 16);
7102 if (!ok) break;
7103 }
7104 if (!ok) break;
7105 if((usehei%16)>0) //Uneven height
7106 {
7107 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) &&
7108 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+usehei-1, special,kb);
7109 }
7110 }
7111 42 break;
7112 }
7113 default:
7114 db=99;
7115 return true;
7116 }
7117 //Z_eventlog("\n");
7118 4311 return ok;
7119 4443 }
7120
7121
7122 1723 bool enemy::canmove(int32_t ndir,zfix s,int32_t special, bool kb)
7123 {
7124
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1723 times.
1723 int32_t usewid = (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) ? hxsz : 16;
7125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1723 times.
1723 int32_t usehei = (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) ? hysz : 16;
7126
1/2
✓ Branch 0 taken 1723 times.
✗ Branch 1 not taken.
1723 if (usewid % 16 != 0) usewid += (16 - (usewid%16));
7127
1/2
✓ Branch 0 taken 1723 times.
✗ Branch 1 not taken.
1723 if (usehei % 16 != 0) usehei += (16 - (usehei%16));
7128 1723 --usewid;
7129 1723 --usehei;
7130 1723 return canmove(ndir,s,special,0,-8,usewid,usehei,kb);
7131 }
7132
7133 2304 bool enemy::canmove(int32_t ndir,int32_t special, bool kb)
7134 {
7135 2304 bool dodongo_move=true; //yes, it's an ugly hack, but we're going to rewrite everything later anyway - DN
7136
7137
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2304 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2304 if(special==spw_clipright&&ndir==right)
7138 {
7139 dodongo_move=canmove(ndir,(zfix)1,special,0,-8,31,15,kb);
7140 }
7141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2304 times.
2304 int32_t usewid = (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) ? hxsz : 16;
7142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2304 times.
2304 int32_t usehei = (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) ? hysz : 16;
7143
1/2
✓ Branch 0 taken 2304 times.
✗ Branch 1 not taken.
2304 if (usewid % 16 != 0) usewid += (16 - (usewid%16));
7144
1/2
✓ Branch 0 taken 2304 times.
✗ Branch 1 not taken.
2304 if (usehei % 16 != 0) usehei += (16 - (usehei%16));
7145 2304 --usewid;
7146 2304 --usehei;
7147
2/2
✓ Branch 0 taken 1015 times.
✓ Branch 1 taken 1289 times.
2304 return canmove(ndir,(zfix)1,special,0,-8,usewid,usehei,kb)&&dodongo_move;
7148 }
7149
7150 186 bool enemy::canmove(int32_t ndir, bool kb)
7151 {
7152 186 return canmove(ndir,(zfix)1,spw_none,0,-8,15,15,kb);
7153 }
7154
7155 // 8-directional
7156 void enemy::newdir_8_old(int32_t newrate,int32_t newhoming,int32_t special,int32_t dx1,int32_t dy1,int32_t dx2,int32_t dy2)
7157 {
7158 int32_t ndir=0;
7159
7160 // can move straight, check if it wants to turn
7161 if(canmove_old(dir,step,special,dx1,dy1,dx2,dy2))
7162 {
7163 if(grumble && (zc_oldrand()&4)<grumble) //Homing
7164 {
7165 int32_t w = Lwpns.idFirst(wBait);
7166
7167 if(w>=0)
7168 {
7169 int32_t bx = Lwpns.spr(w)->x;
7170 int32_t by = Lwpns.spr(w)->y;
7171
7172 ndir = (bx<x) ? left : (bx!=x) ? right : 0;
7173
7174 if(abs(int32_t(y)-by)>14)
7175 {
7176 if(ndir>0) // Already left or right
7177 {
7178 // Making the diagonal directions
7179 ndir += (by<y) ? 2 : 4;
7180 }
7181 else
7182 {
7183 ndir = (by<y) ? up : down;
7184 }
7185 }
7186
7187 if(canmove(ndir,special,false))
7188 {
7189 dir=ndir;
7190 return;
7191 }
7192 }
7193 }
7194
7195 // Homing added.
7196 if(newhoming && (zc_oldrand()&255)<newhoming)
7197 {
7198 ndir = lined_up(8,true);
7199
7200 if(ndir>=0 && canmove(ndir,special,false))
7201 {
7202 dir=ndir;
7203 }
7204
7205 return;
7206 }
7207
7208 int32_t r=zc_oldrand();
7209
7210 if(newrate>0 && !(r%newrate))
7211 {
7212 ndir = ((dir+((r&64)?-1:1))&7)+8;
7213 int32_t ndir2=((dir+((r&64)?1:-1))&7)+8;
7214
7215 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7216 dir=ndir;
7217 else if(canmove(ndir2,step,special,dx1,dy1,dx2,dy2,false))
7218 dir=ndir2;
7219
7220 if(dir==ndir && (newrate>=4)) // newrate>=4, otherwise movement is biased toward upper-left
7221 // due to numerous lost fractional components. -L
7222 {
7223 x.doFloor();
7224 y.doFloor();
7225 }
7226 }
7227
7228 return;
7229 }
7230
7231 // can't move straight, must turn
7232 int32_t i=0;
7233
7234 for(; i<32; i++) // Try random dir
7235 {
7236 ndir=(zc_oldrand()&7)+8;
7237
7238 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7239 break;
7240 }
7241
7242 if(i==32)
7243 {
7244 for(ndir=8; ndir<16; ndir++)
7245 {
7246 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7247 goto ok;
7248 }
7249
7250 ndir = (isSideViewGravity()) ? (zc_oldrand()&1 ? left : right) : -1; // Sideview enemies get trapped if their dir becomes -1
7251 }
7252
7253 ok:
7254 dir=ndir;
7255 x.doFloor();
7256 y.doFloor();
7257 }
7258
7259 205 void enemy::newdir_8(int32_t newrate,int32_t newhoming,int32_t special,int32_t dx1,int32_t dy1,int32_t dx2,int32_t dy2)
7260 {
7261 205 int32_t ndir=0;
7262
7263 // can move straight, check if it wants to turn
7264
2/2
✓ Branch 0 taken 196 times.
✓ Branch 1 taken 9 times.
205 if(canmove(dir,step,special,dx1,dy1,dx2,dy2,false))
7265 {
7266
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 196 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
196 if(grumble && (zc_oldrand()&4)<abs(grumble)) //Homing
7267 {
7268 int32_t i = Lwpns.idFirst(wBait);
7269 if(i >= 0) //idfirst returns -1 if it can't find any
7270 {
7271 weapon *w = (weapon*)Lwpns.spr(i);
7272 if (get_bit(quest_rules, qr_FIND_CLOSEST_BAIT))
7273 {
7274 int32_t currentrange;
7275 if (distance(x, y, w->x, w->y) < w->misc2 || w->misc2 == 0) currentrange = distance(x, y, w->x, w->y);
7276 else currentrange = -1;
7277 int curid = i;
7278 ++i; //increment beforehand cause we just checked the first bait weapon and all others must be after it. ...otherwise it wouldn't be the first. -Deedee
7279 for(; i<Lwpns.Count(); ++i)
7280 {
7281 weapon *lw = (weapon*)Lwpns.spr(i);
7282 if (lw->id == wBait && distance(x, y, lw->x, lw->y) < currentrange && (distance(x, y, lw->x, lw->y) < lw->misc2 || lw->misc2 == 0))
7283 {
7284 currentrange = distance(x, y, lw->x, lw->y);
7285 curid = i;
7286 }
7287 }
7288 i = curid;
7289 if (currentrange == -1) i = -1;
7290 }
7291 else
7292 {
7293 if (!(distance(x, y, w->x, w->y) < w->misc2 || w->misc2 == 0)) i = -1;
7294 }
7295 if(i>=0)
7296 {
7297 int32_t bx = Lwpns.spr(i)->x;
7298 int32_t by = Lwpns.spr(i)->y;
7299
7300 ndir = (bx<x) ? left : (bx!=x) ? right : 0;
7301
7302 if(abs(int32_t(y)-by)>14)
7303 {
7304 if(ndir>0) // Already left or right
7305 {
7306 // Making the diagonal directions
7307 ndir += (by<y) ? 2 : 4;
7308 }
7309 else
7310 {
7311 ndir = (by<y) ? up : down;
7312 }
7313 }
7314 if (grumble < 0 || (itemsbuf[((weapon*)Lwpns.spr(i))->parentitem].flags & ITEM_FLAG1)) ndir = oppositeDir[ndir];
7315 if(canmove(ndir,special,false))
7316 {
7317 dir=ndir;
7318 return;
7319 }
7320 }
7321 }
7322 }
7323
7324 // Homing added.
7325
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 196 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
196 if(newhoming && (zc_oldrand()&255)<abs(newhoming))
7326 {
7327 ndir = lined_up(8,true);
7328 if (newhoming < 0 && ndir >= 0) ndir = oppositeDir[ndir];
7329 if(ndir>=0 && canmove(ndir,special,false))
7330 {
7331 dir=ndir;
7332 }
7333
7334 return;
7335 }
7336
7337 196 int32_t r=zc_oldrand();
7338
7339
4/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 183 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 7 times.
196 if(newrate>0 && !(r%newrate))
7340 {
7341 7 ndir = ((dir+((r&64)?-1:1))&7)+8;
7342 7 int32_t ndir2=((dir+((r&64)?1:-1))&7)+8;
7343
7344
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7345 7 dir=ndir;
7346 else if(canmove(ndir2,step,special,dx1,dy1,dx2,dy2,false))
7347 dir=ndir2;
7348
7349
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 if(dir==ndir && (newrate>=4)) // newrate>=4, otherwise movement is biased toward upper-left
7350 // due to numerous lost fractional components. -L
7351 {
7352 x.doFloor();
7353 y.doFloor();
7354 }
7355 7 }
7356
7357 196 return;
7358 }
7359
7360 // can't move straight, must turn
7361 9 int32_t i=0;
7362
7363
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 for(; i<32; i++) // Try random dir
7364 {
7365 18 ndir=(zc_oldrand()&7)+8;
7366
7367
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7368 9 break;
7369 9 }
7370
7371
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if(i==32)
7372 {
7373 for(ndir=8; ndir<16; ndir++)
7374 {
7375 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7376 goto ok;
7377 }
7378
7379 ndir = (isSideViewGravity()) ? (zc_oldrand()&1 ? left : right) : -1; // Sideview enemies get trapped if their dir becomes -1
7380 }
7381
7382 ok:
7383 9 dir=ndir;
7384 9 x.doFloor();
7385 9 y.doFloor();
7386 205 }
7387
7388 205 void enemy::newdir_8(int32_t newrate,int32_t newhoming,int32_t special)
7389 {
7390 205 newdir_8(newrate,newhoming,special,0,-8,15,15);
7391 205 }
7392
7393 void enemy::newdir_8_old(int32_t newrate,int32_t newhoming,int32_t special)
7394 {
7395 newdir_8_old(newrate,newhoming,special,0,-8,15,15);
7396 }
7397
7398 // makes the enemy slide backwards when hit
7399 // sclk: first byte is clk, second byte is dir
7400 // makes the enemy slide backwards when hit
7401 // sclk: first byte is clk, second byte is dir
7402 34654 int32_t enemy::slide()
7403 {
7404
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34654 times.
34654 if(script_knockback_clk!=0) //scripted knockback
7405 {
7406 sclk = 0;
7407 return 1; //scripted knockback ran
7408 }
7409
5/6
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 34462 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 164 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 28 times.
34654 if(sclk==0 || (hp<=0 && !immortal))
7410 34490 return 0;
7411
7412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 164 times.
164 if(knockbackflags & FLAG_NOSLIDE)
7413 {
7414 sclk = 0;
7415 if(!OFFGRID_ENEMY)
7416 {
7417 //Fix to grid
7418 //x = (int32_t(x)+8)-((int32_t(x)+8)%16);
7419 //y = (int32_t(y)+8)-((int32_t(y)+8)%16);
7420 do_fix(x, 16, true);
7421 do_fix(y, 16, true);
7422 }
7423 return 0;
7424 }
7425
5/10
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 149 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
164 if((sclk&255)==16 && (get_bit(quest_rules,qr_OLD_ENEMY_KNOCKBACK_COLLISION) || knockbackSpeed!=4 ? !canmove(sclk>>8,(zfix) (dmisc2==e2tSPLITHIT ? 1 : 12),0,true) : !canmove(sclk>>8,(zfix) (dmisc2==e2tSPLITHIT ? 1 : knockbackSpeed),0,0,0,15,15,true)))
7426 {
7427 1 sclk=0;
7428 1 return 0;
7429 }
7430
7431 163 --sclk;
7432
7433
3/5
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 41 times.
✓ Branch 4 taken 100 times.
163 switch(sclk>>8)
7434 {
7435 case up:
7436 {
7437
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 22 times.
22 if(y<=(dmisc2==e2tSPLITHIT ? 0 : (get_bit(quest_rules,qr_OLD_ENEMY_KNOCKBACK_COLLISION)?16:0))) //vires
7438 {
7439 sclk=0;
7440 return 0;
7441 }
7442
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
22 if ( dmisc2==e2tSPLITHIT && !canmove(sclk>>8,(zfix)(4),0,true) ) { sclk=0; return 0; } //vires
7443
7444 22 break;
7445 }
7446 case down:
7447 {
7448 if(y>=(dmisc2==e2tSPLITHIT ? 150 : 160)) //was 160 --changed for vires bug.
7449 {
7450 sclk=0;
7451 return 0;
7452 }
7453 if ( dmisc2==e2tSPLITHIT && !canmove(sclk>>8,(zfix)(4),0,true) ) { sclk=0; return 0; } //vires
7454
7455 break;
7456 }
7457 case left:
7458 {
7459
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 41 times.
41 if(x<=(dmisc2==e2tSPLITHIT ? 0 : (get_bit(quest_rules,qr_OLD_ENEMY_KNOCKBACK_COLLISION)?16:0)))
7460 {
7461 sclk=0;
7462 return 0;
7463 }
7464
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
41 if ( dmisc2==e2tSPLITHIT && !canmove(sclk>>8,(zfix)(4),0,true) ) { sclk=0; return 0; }
7465
7466 41 break;
7467 }
7468 case right:
7469 {
7470
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if(x>=(dmisc2==e2tSPLITHIT ? 255 : 240)) //vires
7471 {
7472 sclk=0;
7473 return 0;
7474 }
7475
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
100 if ( dmisc2==e2tSPLITHIT && !canmove(sclk>>8,(zfix)(4),0,true) ) { sclk=0; return 0; } //vires
7476 100 break;
7477 }
7478 }
7479
7480 163 int32_t move = knockbackSpeed;
7481
2/2
✓ Branch 0 taken 154 times.
✓ Branch 1 taken 163 times.
317 while(move>0)
7482 {
7483
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 163 times.
163 int32_t thismove = zc_min(8, move);
7484 163 move -= thismove;
7485 163 hitdir = (sclk>>8);
7486
3/5
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 41 times.
✓ Branch 4 taken 100 times.
163 switch(sclk>>8)
7487 {
7488 case up:
7489 22 y-=thismove;
7490 22 break;
7491
7492 case down:
7493 y+=thismove;
7494 break;
7495
7496 case left:
7497 41 x-=thismove;
7498 41 break;
7499
7500 case right:
7501 100 x+=thismove;
7502 100 break;
7503 }
7504
2/2
✓ Branch 0 taken 154 times.
✓ Branch 1 taken 9 times.
163 if(!canmove(sclk>>8,(zfix)0,0,true))
7505 {
7506
2/3
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
9 switch(sclk>>8)
7507 {
7508 case up:
7509 case down:
7510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(y < 0)
7511 y = 0;
7512
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 else if((int32_t(y)&15) > 7)
7513 y=(int32_t(y)&0xF0)+16;
7514 else
7515 2 y=(int32_t(y)&0xF0);
7516
7517 2 break;
7518
7519 case left:
7520 case right:
7521
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if(x < 0)
7522 x = 0;
7523
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 else if((int32_t(x)&15) > 7)
7524 1 x=(int32_t(x)&0xF0)+16;
7525 else
7526 6 x=(int32_t(x)&0xF0);
7527
7528 7 break;
7529 }
7530
7531 9 sclk=0;
7532 9 clk3=0;
7533 9 break;
7534 }
7535 }
7536
7537
2/2
✓ Branch 0 taken 149 times.
✓ Branch 1 taken 14 times.
163 if((sclk&255)==0)
7538 {
7539 //hitdir = -1;
7540 14 sclk=0;
7541 14 }
7542 163 return 2;
7543 34654 }
7544
7545 bool enemy::can_slide()
7546 {
7547 if(sclk==0 || (hp<=0 && !immortal))
7548 return false;
7549
7550 if((sclk&255)==16 && (get_bit(quest_rules,qr_OLD_ENEMY_KNOCKBACK_COLLISION) || knockbackSpeed!=4 ? !canmove(sclk>>8,(zfix) (dmisc2==e2tSPLITHIT ? 1 : 12),0,true) : !canmove(sclk>>8,(zfix) (dmisc2==e2tSPLITHIT ? 1 : knockbackSpeed),0,true)))
7551 {
7552 return false;
7553 }
7554
7555 return true;
7556 }
7557
7558 bool enemy::fslide()
7559 {
7560 if(sclk==0 || (hp<=0 && !immortal))
7561 return false;
7562
7563 if((sclk&255)==16 && !canmove(sclk>>8,(zfix)12,spw_floater,true))
7564 {
7565 sclk=0;
7566 return false;
7567 }
7568
7569 --sclk;
7570
7571 switch(sclk>>8)
7572 {
7573 case up:
7574 if(y<=16)
7575 {
7576 sclk=0;
7577 return false;
7578 }
7579
7580 break;
7581
7582 case down:
7583 if(y>=160)
7584 {
7585 sclk=0;
7586 return false;
7587 }
7588
7589 break;
7590
7591 case left:
7592 if(x<=16)
7593 {
7594 sclk=0;
7595 return false;
7596 }
7597
7598 break;
7599
7600 case right:
7601 if(x>=240)
7602 {
7603 sclk=0;
7604 return false;
7605 }
7606
7607 break;
7608 }
7609 hitdir = (sclk>>8);
7610 switch(sclk>>8)
7611 {
7612 case up:
7613 y-=4;
7614 break;
7615
7616 case down:
7617 y+=4;
7618 break;
7619
7620 case left:
7621 x-=4;
7622 break;
7623
7624 case right:
7625 x+=4;
7626 break;
7627 }
7628
7629 if(!canmove(sclk>>8,(zfix)0,spw_floater,true))
7630 {
7631 switch(sclk>>8)
7632 {
7633 case up:
7634 case down:
7635 if((int32_t(y)&15) > 7)
7636 y=(int32_t(y)&0xF0)+16;
7637 else
7638 y=(int32_t(y)&0xF0);
7639
7640 break;
7641
7642 case left:
7643 case right:
7644 if((int32_t(x)&15) > 7)
7645 x=(int32_t(x)&0xF0)+16;
7646 else
7647 x=(int32_t(x)&0xF0);
7648
7649 break;
7650 }
7651
7652 sclk=0;
7653 clk3=0;
7654 }
7655
7656 if((sclk&255)==0)
7657 sclk=0;
7658
7659 return true;
7660 }
7661
7662 bool enemy::knockback(int32_t time, int32_t dir, int32_t speed)
7663 {
7664 if((hp<=0 && !immortal)) return false; //No knocking back dead/mid-knockback enemies
7665 if(!canmove(dir,(zfix)speed,0,0,0,15,15,true)) return false; //from slide(); collision check
7666 bool ret = sprite::knockback(time, dir, speed);
7667 if(ret) sclk = 0; //kill engine knockback if interrupted
7668 //! Perhaps also set hitdir here, if needed for timing? -Z
7669 return ret;
7670 }
7671
7672 52054 bool enemy::runKnockback()
7673 {
7674
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52054 times.
52054 if((script_knockback_clk&0xFF)==0)
7675 {
7676 52054 script_knockback_clk = 0;
7677 52054 return false;
7678 }
7679 if(knockbackflags & FLAG_NOSCRIPTKNOCKBACK)
7680 {
7681 return false;
7682 }
7683 int32_t move = script_knockback_speed;
7684 int32_t kb_dir = script_knockback_clk>>8;
7685 --script_knockback_clk;
7686
7687 while(move>0)
7688 {
7689 int32_t thismove = zc_min(get_bit(quest_rules, qr_OLD_SCRIPTED_KNOCKBACK)?8:4, move);
7690 move -= thismove;
7691 hitdir = kb_dir;
7692 switch(kb_dir)
7693 {
7694 case r_up:
7695 case l_up:
7696 case up:
7697 y-=thismove;
7698 break;
7699
7700 case r_down:
7701 case l_down:
7702 case down:
7703 y+=thismove;
7704 break;
7705 }
7706 switch(kb_dir)
7707 {
7708 case l_up:
7709 case l_down:
7710 case left:
7711 x-=thismove;
7712 break;
7713
7714 case r_up:
7715 case r_down:
7716 case right:
7717 x+=thismove;
7718 break;
7719 }
7720 if (get_bit(quest_rules, qr_OLD_SCRIPTED_KNOCKBACK))
7721 {
7722 if(!canmove(kb_dir,(zfix)0,0,true))
7723 {
7724 script_knockback_clk=0;
7725 clk3=0;
7726 //Fix to grid
7727 switch(kb_dir)
7728 {
7729 case up:
7730 case down:
7731 break;
7732 default:
7733 if(x < 0)
7734 x = 0;
7735 else if((int32_t(x)&15) > 7)
7736 x=(int32_t(x)&0xF0)+16;
7737 else
7738 x=(int32_t(x)&0xF0);
7739 break;
7740 }
7741 switch(kb_dir)
7742 {
7743 case left:
7744 case right:
7745 break;
7746 default:
7747 if(y < 0)
7748 y = 0;
7749 else if((int32_t(y)&15) > 7)
7750 y=(int32_t(y)&0xF0)+16;
7751 else
7752 y=(int32_t(y)&0xF0);
7753 break;
7754 }
7755 break;
7756 }
7757 }
7758 else
7759 {
7760 if(!scr_canplace(x,y,0,true))
7761 {
7762 script_knockback_clk=0;
7763 clk3=0;
7764 //Fix to grid
7765 if (OFFGRID_ENEMY)
7766 {
7767 switch(kb_dir)
7768 {
7769 case up:
7770 case down:
7771 break;
7772 default:
7773 if(x < 0)
7774 x = 0;
7775 else if((int32_t(x)&7) > 3)
7776 x=(int32_t(x)&0xF8)+8;
7777 else
7778 x=(int32_t(x)&0xF8);
7779 break;
7780 }
7781 switch(kb_dir)
7782 {
7783 case left:
7784 case right:
7785 break;
7786 default:
7787 if(y < 0)
7788 y = 0;
7789 else if((int32_t(y)&7) > 3)
7790 y=(int32_t(y)&0xF8)+8;
7791 else
7792 y=(int32_t(y)&0xF8);
7793 break;
7794 }
7795 }
7796 else
7797 {
7798 switch(kb_dir)
7799 {
7800 case up:
7801 case down:
7802 break;
7803 default:
7804 if(x < 0)
7805 x = 0;
7806 else if((int32_t(x)&15) > 7)
7807 x=(int32_t(x)&0xF0)+16;
7808 else
7809 x=(int32_t(x)&0xF0);
7810 break;
7811 }
7812 switch(kb_dir)
7813 {
7814 case left:
7815 case right:
7816 break;
7817 default:
7818 if(y < 0)
7819 y = 0;
7820 else if((int32_t(y)&15) > 7)
7821 y=(int32_t(y)&0xF0)+16;
7822 else
7823 y=(int32_t(y)&0xF0);
7824 break;
7825 }
7826 }
7827 break;
7828 }
7829
7830 }
7831 }
7832 return true;
7833 52054 }
7834 // changes enemy's direction, checking restrictions
7835 // rate: 0 = no random changes, 16 = always random change
7836 // homing: 0 = none, 256 = always
7837 // grumble 0 = none, 4 = strongest appetite
7838 1291 void enemy::newdir(int32_t newrate,int32_t newhoming,int32_t special)
7839 {
7840 1291 int32_t ndir=-1;
7841
7842
4/4
✓ Branch 0 taken 1077 times.
✓ Branch 1 taken 214 times.
✓ Branch 2 taken 809 times.
✓ Branch 3 taken 268 times.
1291 if(grumble != 0 && (zc_oldrand()&3)<abs(grumble)) //yes, I know checking if grumble is equal to if grumble == 0, but the latter makes the intention more clear to less experienced coders who might join.
7843 {
7844 268 int32_t i = Lwpns.idFirst(wBait);
7845
1/2
✓ Branch 0 taken 268 times.
✗ Branch 1 not taken.
268 if(i >= 0) //idfirst returns -1 if it can't find any
7846 {
7847 weapon *w = (weapon*)Lwpns.spr(i);
7848 if (get_bit(quest_rules, qr_FIND_CLOSEST_BAIT))
7849 {
7850 int32_t currentrange;
7851 if (distance(x, y, w->x, w->y) < w->misc2 || w->misc2 == 0) currentrange = distance(x, y, w->x, w->y);
7852 else currentrange = -1;
7853 int curid = i;
7854 ++i; //increment beforehand cause we just checked the first bait weapon and all others must be after it. ...otherwise it wouldn't be the first. -Deedee
7855 for(; i<Lwpns.Count(); ++i)
7856 {
7857 weapon *lw = (weapon*)Lwpns.spr(i);
7858 if (lw->id == wBait && distance(x, y, lw->x, lw->y) < currentrange && (distance(x, y, lw->x, lw->y) < lw->misc2 || lw->misc2 == 0))
7859 {
7860 currentrange = distance(x, y, lw->x, lw->y);
7861 curid = i;
7862 }
7863 }
7864 i = curid;
7865 if (currentrange == -1) i = -1;
7866 }
7867 else
7868 {
7869 if (!(distance(x, y, w->x, w->y) < w->misc2 || w->misc2 == 0)) i = -1;
7870 }
7871 if (i >= 0)
7872 {
7873 int32_t bx = Lwpns.spr(i)->x;
7874 int32_t by = Lwpns.spr(i)->y;
7875
7876 if(abs(int32_t(y)-by)>14)
7877 {
7878 ndir = (by<y) ? up : down;
7879 if (grumble < 0 || (itemsbuf[((weapon*)Lwpns.spr(i))->parentitem].flags & ITEM_FLAG1)) ndir = oppositeDir[ndir];
7880 if(canmove(ndir,special,false))
7881 {
7882 dir=ndir;
7883 return;
7884 }
7885 }
7886
7887 ndir = (bx<x) ? left : right;
7888 if (grumble < 0 || (itemsbuf[((weapon*)Lwpns.spr(i))->parentitem].flags & ITEM_FLAG1)) ndir = oppositeDir[ndir];
7889 if(canmove(ndir,special,false))
7890 {
7891 dir=ndir;
7892 return;
7893 }
7894 }
7895 }
7896 268 }
7897
7898
2/2
✓ Branch 0 taken 677 times.
✓ Branch 1 taken 614 times.
1291 if((zc_oldrand()&255)<abs(newhoming))
7899 {
7900 614 ndir = lined_up(8,false);
7901
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 614 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
614 if (newhoming < 0 && ndir >= 0) ndir = oppositeDir[ndir];
7902
4/4
✓ Branch 0 taken 153 times.
✓ Branch 1 taken 461 times.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 127 times.
614 if(ndir>=0 && canmove(ndir,special,false))
7903 {
7904 127 dir=ndir;
7905 127 return;
7906 }
7907 487 }
7908
7909 1164 int32_t i=0;
7910
7911
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2138 times.
2142 for(; i<32; i++)
7912 {
7913 2138 int32_t r=zc_oldrand();
7914
7915
2/2
✓ Branch 0 taken 766 times.
✓ Branch 1 taken 1372 times.
2138 if((r&15)<newrate)
7916 766 ndir=(r>>4)&3;
7917 else
7918 1372 ndir=dir;
7919
7920
2/2
✓ Branch 0 taken 978 times.
✓ Branch 1 taken 1160 times.
2138 if(canmove(ndir,special,false))
7921 1160 break;
7922 978 }
7923
7924
2/2
✓ Branch 0 taken 1160 times.
✓ Branch 1 taken 4 times.
1166 if(i==32)
7925 {
7926
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2 times.
15 for(ndir=0; ndir<4; ndir++)
7927 {
7928
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 2 times.
13 if(canmove(ndir,special,false))
7929 2 goto ok;
7930 11 }
7931
7932
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 ndir = (isSideViewGravity()) ? (zc_oldrand()&1 ? left : right) : -1; // Sideview enemies get trapped if their dir becomes -1
7933 //...Isn't that the point? I'm not sure I understand. Certainly beats phasing through walls... -Dimi
7934 2 }
7935
7936 ok:
7937 1164 dir = ndir;
7938 1291 }
7939
7940 void enemy::newdir()
7941 {
7942 newdir(4,0,spw_none);
7943 }
7944
7945 zfix enemy::distance_left()
7946 {
7947 int32_t a2=x.getInt();
7948 int32_t b2=y.getInt();
7949
7950 switch(dir)
7951 {
7952 case up:
7953 return (zfix)(b2&0xF);
7954
7955 case down:
7956 return (zfix)(16-(b2&0xF));
7957
7958 case left:
7959 return (zfix)(a2&0xF);
7960
7961 case right:
7962 return (zfix)(16-(a2&0xF));
7963 }
7964
7965 return (zfix)0;
7966 }
7967
7968 // keeps walking around
7969 void enemy::constant_walk(int32_t newrate,int32_t newhoming,int32_t special)
7970 {
7971 if(slide())
7972 return;
7973
7974 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock )
7975 return;
7976
7977 if(clk3<=0)
7978 {
7979 fix_coords(true);
7980 newdir(newrate,newhoming,special);
7981
7982 if(step==0)
7983 clk3=0;
7984 else
7985 clk3=int32_t(16.0/step);
7986 }
7987 else if(scored)
7988 {
7989 dir^=1;
7990 if (step != 0) clk3=int32_t(16.0/step)-clk3;
7991 else clk3=32767;
7992 }
7993
7994 if (step != 0) --clk3;
7995 move(step);
7996 }
7997
7998 void enemy::constant_walk()
7999 {
8000 constant_walk(4,0,spw_none);
8001 }
8002
8003 int32_t enemy::pos(int32_t newx,int32_t newy)
8004 {
8005 return (newy<<8)+newx;
8006 }
8007
8008 // for variable step rates
8009 void enemy::variable_walk(int32_t newrate,int32_t newhoming,int32_t special)
8010 {
8011 if(slide())
8012 return;
8013
8014 if(clk<0 || dying || stunclk || watch || step == 0 || ceiling || frozenclock )
8015 return;
8016
8017 zfix dx = (zfix)0;
8018 zfix dy = (zfix)0;
8019
8020 switch(dir)
8021 {
8022 case 8:
8023 case up:
8024 dy-=step;
8025 break;
8026
8027 case 12:
8028 case down:
8029 dy+=step;
8030 break;
8031
8032 case 14:
8033 case left:
8034 dx-=step;
8035 break;
8036
8037 case 10:
8038 case right:
8039 dx+=step;
8040 break;
8041
8042 case 15:
8043 case l_up:
8044 dx-=step;
8045 dy-=step;
8046 break;
8047
8048 case 9:
8049 case r_up:
8050 dx+=step;
8051 dy-=step;
8052 break;
8053
8054 case 13:
8055 case l_down:
8056 dx-=step;
8057 dy+=step;
8058 break;
8059
8060 case 11:
8061 case r_down:
8062 dx+=step;
8063 dy+=step;
8064 break;
8065 }
8066
8067 if(((int32_t(x)&15)==0 && (int32_t(y)&15)==0 && clk3!=pos(x,y)) ||
8068 m_walkflag(int32_t(x+dx),int32_t(y+dy), spw_halfstep, dir))
8069 {
8070 fix_coords();
8071 newdir(newrate,newhoming,special);
8072 clk3=pos(x,y);
8073 }
8074
8075 move(step);
8076 }
8077
8078 // pauses for a while after it makes a complete move (to a new square)
8079 33263 void enemy::halting_walk(int32_t newrate,int32_t newhoming,int32_t special,int32_t newhrate, int32_t haltcnt)
8080 {
8081
4/4
✓ Branch 0 taken 159 times.
✓ Branch 1 taken 33104 times.
✓ Branch 2 taken 150 times.
✓ Branch 3 taken 9 times.
33263 if(sclk && clk2)
8082 {
8083 9 clk3=0;
8084 9 }
8085
8086
8/14
✓ Branch 0 taken 33131 times.
✓ Branch 1 taken 132 times.
✓ Branch 2 taken 33131 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 33131 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 33131 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 33131 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 33131 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 33131 times.
33263 if(slide() || clk<0 || dying || stunclk || watch || ceiling || frozenclock)
8087 {
8088 132 return;
8089 }
8090
8091
2/2
✓ Branch 0 taken 9499 times.
✓ Branch 1 taken 23632 times.
33131 if(clk2>0)
8092 {
8093 9499 --clk2;
8094 9499 return;
8095 }
8096
8097
2/2
✓ Branch 0 taken 1291 times.
✓ Branch 1 taken 22341 times.
23632 if(clk3<=0)
8098 {
8099 1291 fix_coords(true);
8100 1291 newdir(newrate,newhoming,special);
8101 1291 clk3=int32_t(16.0/step);
8102
1/2
✓ Branch 0 taken 1291 times.
✗ Branch 1 not taken.
1291 if (step == 0) clk3 = 32767; //It used to return this in 2.53 and I'm unsure why; I'm guessing dividing by 0 gave max int? Either way, can't be 0 here or scripts break.
8103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1291 times.
1291 if(clk2<0)
8104 {
8105 clk2=0;
8106 }
8107
2/2
✓ Branch 0 taken 237 times.
✓ Branch 1 taken 1054 times.
1291 else if((zc_oldrand()&15)<newhrate)
8108 {
8109 237 clk2=haltcnt;
8110 237 return;
8111 }
8112 1054 }
8113
2/2
✓ Branch 0 taken 22338 times.
✓ Branch 1 taken 3 times.
22341 else if(scored)
8114 {
8115 3 dir^=1;
8116
8117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (step != 0) clk3=int32_t(16.0/step)-clk3;
8118 else clk3=32767;
8119 3 }
8120
8121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23395 times.
23395 if (step != 0) --clk3;
8122 23395 move(step);
8123 33263 }
8124
8125 // 8-directional movement, aligns to 8 pixels
8126 void enemy::constant_walk_8(int32_t newrate,int32_t newhoming,int32_t special)
8127 {
8128 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
8129 return;
8130
8131 if(clk3<=0)
8132 {
8133 newdir_8(newrate,newhoming,special);
8134 clk3=int32_t(8.0/step);
8135 if (step == 0) clk3 = 32767;
8136 }
8137
8138 if (step != 0) --clk3;
8139 move(step);
8140 }
8141 // 8-directional movement, aligns to 8 pixels
8142 void enemy::constant_walk_8_old(int32_t newrate,int32_t newhoming,int32_t special)
8143 {
8144 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
8145 return;
8146
8147 if(clk3<=0)
8148 {
8149 newdir_8(newrate,newhoming,special);
8150 clk3=int32_t(8.0/step);
8151 if (step == 0) clk3 = 32767;
8152 }
8153
8154 if (step != 0) --clk3;
8155 move(step);
8156 }
8157
8158 void enemy::halting_walk_8(int32_t newrate,int32_t newhoming, int32_t newclk,int32_t special,int32_t newhrate, int32_t haltcnt)
8159 {
8160 if(clk<0 || dying || stunclk || watch || frozenclock)
8161 return;
8162
8163 if(!canmove(dir,step,special,false))
8164 clk3=0;
8165
8166 if(clk2>0)
8167 {
8168 --clk2;
8169 return;
8170 }
8171
8172 if(clk3<=0)
8173 {
8174 newdir_8(newrate,newhoming,special);
8175 clk3=newclk;
8176
8177 if(clk2<0)
8178 {
8179 clk2=0;
8180 }
8181 else if((zc_oldrand()&15)<newhrate)
8182 {
8183 newdir_8(newrate,newhoming,special);
8184 clk2=haltcnt;
8185 return;
8186 }
8187 }
8188
8189 --clk3;
8190 move(step);
8191 }
8192
8193 // 8-directional movement, no alignment
8194 1846 void enemy::variable_walk_8(int32_t newrate,int32_t newhoming, int32_t newclk,int32_t special)
8195 {
8196
7/12
✓ Branch 0 taken 1545 times.
✓ Branch 1 taken 301 times.
✓ Branch 2 taken 1545 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1545 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1545 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1545 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1545 times.
1846 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
8197 301 return;
8198
8199
2/2
✓ Branch 0 taken 1536 times.
✓ Branch 1 taken 9 times.
1545 if(!canmove(dir,step,special,false))
8200 9 clk3=0;
8201
8202
2/2
✓ Branch 0 taken 1340 times.
✓ Branch 1 taken 205 times.
1545 if(clk3<=0)
8203 {
8204 205 newdir_8(newrate,newhoming,special);
8205 205 clk3=newclk;
8206 205 }
8207
8208 1545 --clk3;
8209 1545 move(step);
8210 1846 }
8211
8212 // same as above but with variable enemy size
8213 void enemy::variable_walk_8(int32_t newrate,int32_t newhoming, int32_t newclk,int32_t special,int32_t dx1,int32_t dy1,int32_t dx2,int32_t dy2)
8214 {
8215 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
8216 return;
8217
8218 if(!canmove(dir,step,special,dx1,dy1,dx2,dy2,false))
8219 clk3=0;
8220
8221 if(clk3<=0)
8222 {
8223 newdir_8(newrate,newhoming,special,dx1,dy1,dx2,dy2);
8224 clk3=newclk;
8225 }
8226
8227 --clk3;
8228 move(step);
8229 }
8230
8231 // the variable speed floater movement
8232 // ms is max speed
8233 // ss is step speed
8234 // s is step count
8235 // p is pause count
8236 // g is graduality :)
8237 //floater_walk(rate,hrate,dstep/100,(zfix)0,10,dmisc16,dmisc17);
8238 1846 void enemy::floater_walk(int32_t newrate,int32_t newclk,zfix ms,zfix ss,int32_t s,int32_t p, int32_t g)
8239 {
8240 1846 ++clk2;
8241 1846 byte over_pit = overpit(this);
8242
8243
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1846 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1846 if(dmisc1 && over_pit) p = 0;
8244
2/5
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 1753 times.
✓ Branch 3 taken 93 times.
✗ Branch 4 not taken.
1846 switch(movestatus)
8245 {
8246 //! This needs a case 4 (landing)....if we want to halt, we move to case 4, and
8247 //! if the conditions prevent it, we jump back to case 2.
8248 case 0: // paused
8249 if(clk2>=p)
8250 {
8251 movestatus=1;
8252 clk2=0;
8253 }
8254
8255 break;
8256
8257 case 1: // speeding up
8258
1/2
✓ Branch 0 taken 1753 times.
✗ Branch 1 not taken.
1753 if (s >= 0)
8259 {
8260
2/2
✓ Branch 0 taken 1746 times.
✓ Branch 1 taken 7 times.
1753 if(clk2<g*s)
8261 {
8262
2/2
✓ Branch 0 taken 1632 times.
✓ Branch 1 taken 114 times.
1746 if(!((clk2-1)%g))
8263 114 step+=ss;
8264 1746 }
8265 else
8266 {
8267 7 movestatus=2;
8268 7 clk2=0;
8269 }
8270 1753 }
8271 else
8272 {
8273 if(step < ms)
8274 {
8275 if(!((clk2-1)%g))
8276 {
8277 step+=ss;
8278 if (step >= ms) step = ms;
8279 }
8280 }
8281 else
8282 {
8283 step = ms;
8284 movestatus=2;
8285 clk2=0;
8286 }
8287 }
8288
8289 1753 break;
8290
8291 case 2: // normal
8292 93 step=ms;
8293
8294
5/8
✗ Branch 0 not taken.
✓ Branch 1 taken 93 times.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 33 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 33 times.
✓ Branch 6 taken 33 times.
✗ Branch 7 not taken.
93 if(clk2>(dmisc15>0?dmisc15:48) && !(zc_oldrand()%(dmisc14>0?dmisc14:768)))
8295 {
8296 if (s >= 0) step=ss*s;
8297 else step=ms;
8298 movestatus=3;
8299 clk2=0;
8300 }
8301
8302 93 break;
8303
8304 case 3: // slowing down
8305 if (s >= 0)
8306 {
8307 if(clk2<=g*s)
8308 {
8309 { //don't slow down over pits
8310
8311 if(over_pit)
8312 {
8313 if(dmisc1)
8314 {
8315 step=ms;
8316 }
8317 }
8318 else //can slow down
8319 {
8320 if(!(clk2%g) && !dmisc1)
8321 step-=ss;
8322 }
8323 }
8324
8325
8326 }
8327 else
8328 {
8329 //if((moveflags&FLAG_CAN_PITFALL)) //don't check pits if the enemy ignores them
8330 //this doesn't help keese, as they have a z of 0.
8331 //they always nee to run this check.
8332 {
8333 if(over_pit &&!dmisc1)
8334 {
8335 --clk2; //if over a pit, don't land, and revert clock change
8336 }
8337 else //can land safely
8338 {
8339 movestatus=0;
8340 if(dmisc1&&!over_pit)
8341 step=0;
8342 clk2=0;
8343 }
8344 }
8345
8346 }
8347 }
8348 else
8349 {
8350 if(step > 0)
8351 {
8352 if(over_pit)
8353 {
8354 if(dmisc1)
8355 {
8356 step=ms;
8357 }
8358 }
8359 else //can slow down
8360 {
8361 if(!(clk2%g))
8362 step-=ss;
8363 }
8364 }
8365 else
8366 {
8367 //if((moveflags&FLAG_CAN_PITFALL)) //don't check pits if the enemy ignores them
8368 //this doesn't help keese, as they have a z of 0.
8369 //they always nee to run this check.
8370 if(over_pit)
8371 {
8372 step+=ss; //if over a pit, don't land, and revert clock change
8373 }
8374 else //can land safely
8375 {
8376 movestatus=0;
8377 step=0;
8378 clk2=0;
8379 }
8380 }
8381 }
8382
8383 break;
8384 }
8385
8386
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 1746 times.
1846 variable_walk_8(movestatus==2?newrate:0,homing,newclk,spw_floater);
8387 1846 }
8388
8389 void enemy::floater_walk(int32_t newrate,int32_t newclk,zfix s)
8390 {
8391 floater_walk(newrate,newclk,s,(zfix)0.125,3,80,32);
8392 }
8393
8394 // Checks if enemy is lined up with Hero. If so, returns direction Hero is
8395 // at as compared to enemy. Returns -1 if not lined up. Range is inclusive.
8396 614 int32_t enemy::lined_up(int32_t range, bool dir8)
8397 {
8398 614 int32_t lx = Hero.getX();
8399 614 int32_t ly = Hero.getY();
8400
8401
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 569 times.
614 if(abs(lx-int32_t(x))<=range)
8402 {
8403
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 18 times.
45 if(ly<y)
8404 {
8405 27 return up;
8406 }
8407
8408 18 return down;
8409 }
8410
8411
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 461 times.
569 if(abs(ly-int32_t(y))<=range)
8412 {
8413
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 56 times.
108 if(lx<x)
8414 {
8415 52 return left;
8416 }
8417
8418 56 return right;
8419 }
8420
8421
1/2
✓ Branch 0 taken 461 times.
✗ Branch 1 not taken.
461 if(dir8)
8422 {
8423 if(abs(lx-x)-abs(ly-y)<=range)
8424 //if(abs(lx-x)-abs(ly-y)<=range && abs(ly-y)-abs(lx-x)<=range) //Fix floating enemies not seeking hero. -Tamamo
8425 {
8426 if(ly<y)
8427 {
8428 if(lx<x)
8429 {
8430 return l_up;
8431 }
8432 else
8433 {
8434 return r_up;
8435 }
8436 }
8437 else
8438 {
8439 if(lx<x)
8440 {
8441 return l_down;
8442 }
8443 else
8444 {
8445 return r_down;
8446 }
8447 }
8448 }
8449 }
8450
8451 461 return -1;
8452 614 }
8453
8454 // returns true if Hero is within 'range' pixels of the enemy
8455 1 bool enemy::HeroInRange(int32_t range)
8456 {
8457 1 int32_t lx = Hero.getX();
8458 1 int32_t ly = Hero.getY();
8459
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 return abs(lx-int32_t(x))<=range && abs(ly-int32_t(y))<=range;
8460 }
8461
8462 // place the enemy in line with Hero (red wizzrobes)
8463 void enemy::place_on_axis(bool floater, bool solid_ok)
8464 {
8465 int32_t lx=zc_min(zc_max(int32_t(Hero.getX())&0xF0,32),208);
8466 int32_t ly=zc_min(zc_max(int32_t(Hero.getY())&0xF0,32),128);
8467 int32_t pos2=zc_oldrand()%23;
8468 int32_t tried=0;
8469 bool last_resort,placed=false;
8470
8471
8472 do
8473 {
8474 if(pos2<14)
8475 {
8476 x=(pos2<<4)+16;
8477 y=ly;
8478 }
8479 else
8480 {
8481 x=lx;
8482 y=((pos2-14)<<4)+16;
8483 }
8484
8485 // Don't commit to a last resort if position is out of bounds.
8486 last_resort= !(x<32 || y<32 || x>=224 || y>=144);
8487
8488 if(abs(lx-int32_t(x))>16 || abs(ly-int32_t(y))>16)
8489 {
8490 // Red Wizzrobes should be able to appear on water, but not other
8491 // solid combos; however, they could appear on solid combos in 2.10,
8492 // and some quests depend on that.
8493 if((solid_ok || !m_walkflag(x,y,floater ? spw_water : spw_door, dir))
8494 && !flyerblocked(x,y,floater ? spw_floater : spw_door))
8495 placed=true;
8496 }
8497
8498 if(!placed && tried>=22 && last_resort)
8499 {
8500 placed=true;
8501 }
8502
8503 ++tried;
8504 pos2=(pos2+3)%23;
8505 }
8506 while(!placed);
8507
8508 if(y==ly)
8509 dir=(x<lx)?right:left;
8510 else
8511 dir=(y<ly)?down:up;
8512
8513 clk2=tried;
8514 }
8515
8516 23619 int32_t enemy::n_frame_n_dir(int32_t frames, int32_t ndir, int32_t f4)
8517 {
8518 23619 int32_t t = o_tile;
8519 23619 int32_t b = o_tile;
8520
8521 // Darknuts, but also Wizzrobes and Wallmasters
8522
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 23619 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
23619 switch(family)
8523 {
8524 case eeWALK:
8525
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 23619 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
23619 if(dmisc9==e9tPOLSVOICE && clk2>=0 && do_animation)
8526 {
8527 tile=s_tile;
8528 t=s_tile;
8529 b=s_tile;
8530 }
8531
8532 23619 break;
8533
8534 case eeTRAP:
8535 if(dummy_int[1] && guysbuf[id].flags2 & eneflag_trp2 && do_animation) // Just to make sure
8536 {
8537 tile=s_tile;
8538 t=s_tile;
8539 b=s_tile;
8540 }
8541
8542 break;
8543
8544 case eeSPINTILE:
8545 if(misc>=96 && do_animation)
8546 {
8547 tile=o_tile+frames*ndir;
8548 t=tile;
8549 }
8550
8551 break;
8552 }
8553
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23619 times.
23619 if ( do_animation )
8554 {
8555
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 23619 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 23619 times.
23619 if(ndir!=0) switch(frames)
8556 {
8557 case 2:
8558 tiledir_small(dir,ndir==4);
8559 break;
8560
8561 case 3:
8562 tiledir_three(dir);
8563 break;
8564
8565 case 4:
8566 23619 tiledir(dir,ndir==4);
8567 23619 break;
8568 23619 }
8569
8570
1/2
✓ Branch 0 taken 23619 times.
✗ Branch 1 not taken.
23619 if(family==eeWALK)
8571
6/6
✓ Branch 0 taken 19527 times.
✓ Branch 1 taken 4092 times.
✓ Branch 2 taken 18012 times.
✓ Branch 3 taken 5607 times.
✓ Branch 4 taken 4645 times.
✓ Branch 5 taken 962 times.
23619 tile=zc_min(tile+f4, t+frames*(zc_max(dir, 0)+1)-1);
8572 else
8573 tile+=f4;
8574 23619 }
8575 23619 return b;
8576 }
8577
8578 void enemy::tiledir_three(int32_t ndir)
8579 {
8580 if ( !do_animation ) return;
8581 flip=0;
8582
8583 switch(ndir)
8584 {
8585 case right:
8586 tile+=3;
8587 [[fallthrough]];
8588
8589 case left:
8590 tile+=3;
8591 [[fallthrough]];
8592
8593 case down:
8594 tile+=3;
8595 [[fallthrough]];
8596
8597 case up:
8598 break;
8599 }
8600 }
8601
8602 void enemy::tiledir_small(int32_t ndir, bool fourdir)
8603 {
8604 if ( !do_animation ) return;
8605 flip=0;
8606
8607 switch(ndir)
8608 {
8609 case 8:
8610 case up:
8611 break;
8612
8613 case 12:
8614 case down:
8615 tile+=2;
8616 break;
8617
8618 case 14:
8619 case left:
8620 tile+=4;
8621 break;
8622
8623 case 10:
8624 case right:
8625 tile+=6;
8626 break;
8627
8628 case 9:
8629 case r_up:
8630 if(fourdir)
8631 break;
8632
8633 tile+=10;
8634 break;
8635
8636 case 11:
8637 case r_down:
8638 if(fourdir)
8639 tile+=2;
8640 else
8641 tile+=14;
8642
8643 break;
8644
8645 case 13:
8646 case l_down:
8647 if(fourdir)
8648 tile+=2;
8649 else
8650 tile+=12;
8651
8652 break;
8653
8654 case 15:
8655 case l_up:
8656 if(fourdir)
8657 break;
8658
8659 tile+=8;
8660 break;
8661
8662 default:
8663 //dir=(zc_oldrand()*100)%8;
8664 //tiledir_small(dir);
8665 // flip=zc_oldrand()&3;
8666 // tile=(zc_oldrand()*100000)%NEWMAXTILES;
8667 break;
8668 }
8669 }
8670
8671 23619 void enemy::tiledir(int32_t ndir, bool fourdir)
8672 {
8673
1/2
✓ Branch 0 taken 23619 times.
✗ Branch 1 not taken.
23619 if ( !do_animation ) return;
8674 23619 flip=0;
8675
8676
4/9
✓ Branch 0 taken 4092 times.
✓ Branch 1 taken 4659 times.
✓ Branch 2 taken 7317 times.
✓ Branch 3 taken 7551 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
23619 switch(ndir)
8677 {
8678 case 8:
8679 case up:
8680 4092 break;
8681
8682 case 12:
8683 case down:
8684 4659 tile+=4;
8685 4659 break;
8686
8687 case 14:
8688 case left:
8689 7317 tile+=8;
8690 7317 break;
8691
8692 case 10:
8693 case right:
8694 7551 tile+=12;
8695 7551 break;
8696
8697 case 9:
8698 case r_up:
8699 if(fourdir)
8700 break;
8701 else
8702 tile+=24;
8703
8704 break;
8705
8706 case 11:
8707 case r_down:
8708 if(fourdir)
8709 tile+=4;
8710 else
8711 tile+=32;
8712
8713 break;
8714
8715 case 13:
8716 case l_down:
8717 if(fourdir)
8718 tile+=4;
8719 else
8720 tile+=28;
8721
8722 break;
8723
8724 case 15:
8725 case l_up:
8726 if(fourdir)
8727 break;
8728 else
8729 tile+=20;
8730
8731 break;
8732
8733 default:
8734 //dir=(zc_oldrand()*100)%8;
8735 //tiledir(dir);
8736 // flip=zc_oldrand()&3;
8737 // tile=(zc_oldrand()*100000)%NEWMAXTILES;
8738 break;
8739 }
8740 23619 }
8741
8742 void enemy::tiledir_big(int32_t ndir, bool fourdir)
8743 {
8744 if ( !do_animation ) return;
8745 flip=0;
8746
8747 switch(ndir)
8748 {
8749 case 8:
8750 case up:
8751 break;
8752
8753 case 12:
8754 case down:
8755 tile+=8;
8756 break;
8757
8758 case 14:
8759 case left:
8760 tile+=40;
8761 break;
8762
8763 case 10:
8764 case right:
8765 tile+=48;
8766 break;
8767
8768 case 9:
8769 case r_up:
8770 if(fourdir)
8771 break;
8772
8773 tile+=88;
8774 break;
8775
8776 case 11:
8777 case r_down:
8778 if(fourdir)
8779 tile+=8;
8780 else
8781 tile+=128;
8782
8783 break;
8784
8785 case 13:
8786 case l_down:
8787 if(fourdir)
8788 tile+=8;
8789 else
8790 tile+=120;
8791
8792 break;
8793
8794 case 15:
8795 case l_up:
8796 if(fourdir)
8797 break;
8798
8799 tile+=80;
8800 break;
8801
8802 default:
8803 //dir=(zc_oldrand()*100)%8;
8804 //tiledir_big(dir);
8805 // flip=zc_oldrand()&3;
8806 // tile=(zc_oldrand()*100000)%NEWMAXTILES;
8807 break;
8808 }
8809 }
8810
8811 54161 void enemy::update_enemy_frame()
8812 {
8813
2/4
✓ Branch 0 taken 54161 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 54161 times.
54161 if(fallclk||drownclk) return;
8814
1/2
✓ Branch 0 taken 54161 times.
✗ Branch 1 not taken.
54161 if (!do_animation)
8815 return;
8816
8817
3/4
✓ Branch 0 taken 23619 times.
✓ Branch 1 taken 30542 times.
✓ Branch 2 taken 23619 times.
✗ Branch 3 not taken.
54161 if (get_bit(quest_rules,qr_OLD_TILE_INITIALIZATION) || tile == 0) tile = o_tile; //tile was initialized here before. It needs to be initialized here as well.
8818
8819
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
54161 if(get_bit(quest_rules,qr_ANONE_NOANIM)
8820
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54161 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
54161 && anim == aNONE && family != eeGUY)
8821 return;
8822
1/2
✓ Branch 0 taken 54161 times.
✗ Branch 1 not taken.
54161 int32_t newfrate = zc_max(frate,4);
8823 54161 int32_t f4=abs(clk/(newfrate/4)); // casts clk to [0,1,2,3]
8824 54161 int32_t f2=abs(clk/(newfrate/2)); // casts clk to [0,1]
8825
2/2
✓ Branch 0 taken 23619 times.
✓ Branch 1 taken 30542 times.
54161 int32_t fx = get_bit(quest_rules, qr_NEWENEMYTILES) ? f4 : f2;
8826 54161 tile = o_tile;
8827 54161 int32_t basetile = o_tile;
8828 54161 int32_t tilerows = 1; // How many rows of tiles? The Extend code needs to know.
8829 54161 bool ignore_extend = false;
8830
11/40
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3846 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 4548 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1454 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 505 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 9408 times.
✓ Branch 23 taken 1796 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 23619 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 4371 times.
✓ Branch 30 taken 1524 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 2369 times.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 721 times.
✗ Branch 39 not taken.
54161 switch(anim)
8831 {
8832
8833 case aDONGO:
8834 {
8835 int32_t fr = stunclk>0 ? 16 : 8;
8836
8837 if(!dying && clk2>0 && clk2<=64)
8838 {
8839 // bloated
8840 switch(dir)
8841 {
8842 case up:
8843 tile+=9;
8844 flip=0;
8845 xofs=0;
8846 dummy_int[1]=0; //no additional tiles
8847 break;
8848
8849 case down:
8850 tile+=7;
8851 flip=0;
8852 xofs=0;
8853 dummy_int[1]=0; //no additional tiles
8854 break;
8855
8856 case left:
8857 flip=1;
8858 tile+=4;
8859 xofs=16;
8860 dummy_int[1]=1; //second tile is next tile
8861 break;
8862
8863 case right:
8864 flip=0;
8865 tile+=5;
8866 xofs=16;
8867 dummy_int[1]=-1; //second tile is previous tile
8868 break;
8869 }
8870 }
8871 else if(!dying || clk2>19)
8872 {
8873 // normal
8874 switch(dir)
8875 {
8876 case up:
8877 tile+=8;
8878 flip=(clk&fr)?1:0;
8879 xofs=0;
8880 dummy_int[1]=0; //no additional tiles
8881 break;
8882
8883 case down:
8884 tile+=6;
8885 flip=(clk&fr)?1:0;
8886 xofs=0;
8887 dummy_int[1]=0; //no additional tiles
8888 break;
8889
8890 case left:
8891 flip=1;
8892 tile+=(clk&fr)?2:0;
8893 xofs=16;
8894 dummy_int[1]=1; //second tile is next tile
8895 break;
8896
8897 case right:
8898 flip=0;
8899 tile+=(clk&fr)?3:1;
8900 xofs=16;
8901 dummy_int[1]=-1; //second tile is next tile
8902 break;
8903 }
8904 }
8905 }
8906 break;
8907
8908 case aNEWDONGO:
8909 {
8910 int32_t fr4=0;
8911
8912 if(!dying && clk2>0 && clk2<=64)
8913 {
8914 // bloated
8915 if(clk2>=0)
8916 {
8917 fr4=3;
8918 }
8919
8920 if(clk2>=16)
8921 {
8922 fr4=2;
8923 }
8924
8925 if(clk2>=32)
8926 {
8927 fr4=1;
8928 }
8929
8930 if(clk2>=48)
8931 {
8932 fr4=0;
8933 }
8934
8935 switch(dir)
8936 {
8937 case up:
8938 xofs=0;
8939 tile+=8+fr4;
8940 dummy_int[1]=0; //no additional tiles
8941 break;
8942
8943 case down:
8944 xofs=0;
8945 tile+=12+fr4;
8946 dummy_int[1]=0; //no additional tiles
8947 break;
8948
8949 case left:
8950 tile+=29+(2*fr4);
8951 xofs=16;
8952 dummy_int[1]=-1; //second tile is previous tile
8953 break;
8954
8955 case right:
8956 tile+=49+(2*fr4);
8957 xofs=16;
8958 dummy_int[1]=-1; //second tile is previous tile
8959 break;
8960 }
8961 }
8962 else if(!dying || clk2>19)
8963 {
8964 // normal
8965 switch(dir)
8966 {
8967 case up:
8968 xofs=0;
8969 tile+=((clk&12)>>2);
8970 dummy_int[1]=0; //no additional tiles
8971 break;
8972
8973 case down:
8974 xofs=0;
8975 tile+=4+((clk&12)>>2);
8976 dummy_int[1]=0; //no additional tiles
8977 break;
8978
8979 case left:
8980 tile+=21+((clk&12)>>1);
8981 xofs=16;
8982 dummy_int[1]=-1; //second tile is previous tile
8983 break;
8984
8985 case right:
8986 flip=0;
8987 tile+=41+((clk&12)>>1);
8988 xofs=16;
8989 dummy_int[1]=-1; //second tile is previous tile
8990 break;
8991 }
8992 }
8993 }
8994 break;
8995
8996 case aDONGOBS:
8997 {
8998 int32_t fr4=0;
8999
9000 if(!dying && clk2>0 && clk2<=64)
9001 {
9002 // bloated
9003 if(clk2>=0)
9004 {
9005 fr4=3;
9006 }
9007
9008 if(clk2>=16)
9009 {
9010 fr4=2;
9011 }
9012
9013 if(clk2>=32)
9014 {
9015 fr4=1;
9016 }
9017
9018 if(clk2>=48)
9019 {
9020 fr4=0;
9021 }
9022
9023 switch(dir)
9024 {
9025 case up:
9026 tile+=28+fr4;
9027 yofs+=8;
9028 dummy_int[1]=-20; //second tile change
9029 dummy_int[2]=0; //new xofs change
9030 dummy_int[3]=-16; //new xofs change
9031 break;
9032
9033 case down:
9034 tile+=12+fr4;
9035 yofs-=8;
9036 dummy_int[1]=20; //second tile change
9037 dummy_int[2]=0; //new xofs change
9038 dummy_int[3]=16; //new xofs change
9039 break;
9040
9041 case left:
9042 tile+=49+(2*fr4);
9043 xofs+=8;
9044 dummy_int[1]=-1; //second tile change
9045 dummy_int[2]=-16; //new xofs change
9046 dummy_int[3]=0; //new xofs change
9047 break;
9048
9049 case right:
9050 tile+=69+(2*fr4);
9051 xofs+=8;
9052 dummy_int[1]=-1; //second tile change
9053 dummy_int[2]=-16; //new xofs change
9054 dummy_int[3]=0; //new xofs change
9055 break;
9056 }
9057 }
9058 else if(!dying || clk2>19)
9059 {
9060 // normal
9061 switch(dir)
9062 {
9063 case up:
9064 tile+=20+((clk&24)>>3);
9065 yofs+=8;
9066 dummy_int[1]=-20; //second tile change
9067 dummy_int[2]=0; //new xofs change
9068 dummy_int[3]=-16; //new xofs change
9069 break;
9070
9071 case down:
9072 tile+=4+((clk&24)>>3);
9073 yofs-=8;
9074 dummy_int[1]=20; //second tile change
9075 dummy_int[2]=0; //new xofs change
9076 dummy_int[3]=16; //new xofs change
9077 break;
9078
9079 case left:
9080 xofs=-8;
9081 tile+=40+((clk&24)>>2);
9082 dummy_int[1]=1; //second tile change
9083 dummy_int[2]=16; //new xofs change
9084 dummy_int[3]=0; //new xofs change
9085 break;
9086
9087 case right:
9088 tile+=60+((clk&24)>>2);
9089 xofs=-8;
9090 dummy_int[1]=1; //second tile change
9091 dummy_int[2]=16; //new xofs change
9092 dummy_int[3]=0; //new xofs change
9093 break;
9094 }
9095 }
9096 }
9097 break;
9098
9099 case aWIZZ:
9100 {
9101 // if(d->misc1)
9102 if(dmisc1)
9103 {
9104 if(clk&8)
9105 {
9106 ++tile;
9107 }
9108 }
9109 else
9110 {
9111 if(frame&4)
9112 {
9113 ++tile;
9114 }
9115 }
9116
9117 switch(dir)
9118 {
9119 case 9:
9120 case 15:
9121 case up:
9122 tile+=2;
9123 break;
9124
9125 case down:
9126 break;
9127
9128 case 13:
9129 case left:
9130 flip=1;
9131 break;
9132
9133 default:
9134 flip=0;
9135 break;
9136 }
9137 }
9138 break;
9139
9140 case aNEWWIZZ:
9141 {
9142 tiledir(dir,true);
9143
9144 // if(d->misc1) //walking wizzrobe
9145 if(dmisc1) //walking wizzrobe
9146 {
9147 if(clk&8)
9148 {
9149 tile+=2;
9150 }
9151
9152 if(clk&4)
9153 {
9154 tile+=1;
9155 }
9156
9157 if(!(dummy_bool[1]||dummy_bool[2])) //should never be charging or firing for these wizzrobes
9158 {
9159 if(dummy_int[1]>0)
9160 {
9161 tile+=40;
9162 }
9163 }
9164 }
9165 else
9166 {
9167 if(dummy_bool[1]||dummy_bool[2])
9168 {
9169 tile+=20;
9170
9171 if(dummy_bool[2])
9172 {
9173 tile+=20;
9174 }
9175 }
9176
9177 tile+=((frame>>1)&3);
9178 }
9179 }
9180 break;
9181
9182 case a3FRM:
9183 {
9184 basetile = n_frame_n_dir(3, 0, (f4==3) ? 1 : f4);
9185 }
9186 break;
9187
9188 case a3FRM4DIR:
9189 {
9190 basetile = n_frame_n_dir(3, 4, (f4==3) ? 1 : f4);
9191 }
9192 break;
9193
9194 case aVIRE:
9195 {
9196 if(dir==up)
9197 {
9198 tile+=2;
9199 }
9200
9201 tile+=fx;
9202 }
9203 break;
9204
9205 case aROPE:
9206 {
9207 tile+=(1-fx);
9208 flip = dir==left ? 1:0;
9209 }
9210 break;
9211
9212 case aZORA:
9213 {
9214 int32_t dl;
9215
9216
2/2
✓ Branch 0 taken 99 times.
✓ Branch 1 taken 406 times.
505 if(clk<36)
9217 {
9218 99 dl=clk+5;
9219 99 goto waves2;
9220 }
9221
9222
2/2
✓ Branch 0 taken 198 times.
✓ Branch 1 taken 208 times.
406 if(clk<36+66)
9223
1/2
✓ Branch 0 taken 198 times.
✗ Branch 1 not taken.
198 tile=(dir==up)?o_tile+1:o_tile;
9224 else
9225 {
9226 208 dl=clk-36-66;
9227 waves2:
9228 307 tile=((dl/11)&1)+s_tile;
9229 307 basetile = s_tile;
9230 }
9231 }
9232 505 break;
9233
9234 case aNEWZORA:
9235 {
9236 f4=(clk/16)%4;
9237
9238 tiledir(dir,true);
9239 int32_t dl;
9240
9241 if((clk>35)&&(clk<36+67)) //surfaced
9242 {
9243 if((clk>=(35+10))&&(clk<(38+56))) //mouth open
9244 {
9245 tile+=80;
9246 } //mouth closed
9247 else
9248 {
9249 tile+=40;
9250 }
9251
9252 tile+=f4;
9253 }
9254 else
9255 {
9256 if(clk<36)
9257 {
9258 dl=clk+5;
9259 }
9260 else
9261 {
9262 dl=clk-36-66;
9263 }
9264
9265 tile+=((dl/5)&3);
9266 }
9267 }
9268 break;
9269
9270 case a4FRM4EYE:
9271 case a2FRM4EYE:
9272 case a4FRM8EYE:
9273 case a4FRM8EYEB: //big version
9274 case a4FRM4EYEB:
9275 {
9276 tilerows = 2;
9277 int fakex = x + 8*(zc_max(1,txsz)-1);
9278 int fakey = y + 8*(zc_max(1,tysz)-1);
9279 double _MSVC2022_tmp1, _MSVC2022_tmp2;
9280 double ddir=atan2_MSVC2022_FIX(double(fakey-(Hero.y)),double(Hero.x-fakex));
9281 int32_t lookat=zc_oldrand()&15;
9282
9283 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
9284 {
9285 lookat=l_down;
9286 }
9287 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
9288 {
9289 lookat=down;
9290 }
9291 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
9292 {
9293 lookat=r_down;
9294 }
9295 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
9296 {
9297 lookat=right;
9298 }
9299 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
9300 {
9301 lookat=r_up;
9302 }
9303 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
9304 {
9305 lookat=up;
9306 }
9307 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
9308 {
9309 lookat=l_up;
9310 }
9311 else
9312 {
9313 lookat=left;
9314 }
9315
9316 int32_t dir2 = dir;
9317 dir = lookat;
9318 if (anim != a4FRM8EYEB && anim != a4FRM4EYEB) basetile = n_frame_n_dir(anim==a2FRM4EYE ? 2:4, anim==a4FRM8EYE ? 8 : 4, anim==a2FRM4EYE ? (f2&1):f4);
9319 else
9320 {
9321 tiledir_big(dir,(anim == a4FRM4EYEB));
9322 tile+=2*f4;
9323 ignore_extend = true;
9324 }
9325 dir = dir2;
9326 }
9327 break;
9328
9329 case aFLIP:
9330 {
9331 9408 flip = f2&1;
9332 }
9333 9408 break;
9334
9335 case a2FRM:
9336 {
9337 1796 tile += (1-f2);
9338 }
9339 1796 break;
9340
9341 case a2FRMB:
9342 {
9343 tile+= 2*(1-f2);
9344 ignore_extend = true;
9345 }
9346 break;
9347
9348 case a2FRM4DIR:
9349 {
9350 basetile = n_frame_n_dir(2, 4, f2&1);
9351 }
9352 break;
9353
9354 case a4FRM4DIRF:
9355 {
9356 23619 basetile = n_frame_n_dir(4,4,f4);
9357
9358
2/2
✓ Branch 0 taken 16113 times.
✓ Branch 1 taken 7506 times.
23619 if(clk2>0) //stopped to fire
9359 {
9360 7506 tile+=20;
9361
9362
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 2448 times.
7506 if(clk2<17) //firing
9363 {
9364 2448 tile+=20;
9365 2448 }
9366 7506 }
9367 }
9368 23619 break;
9369
9370 case a4FRM4DIR:
9371 {
9372 basetile = n_frame_n_dir(4,4,f4);
9373 }
9374 break;
9375
9376 case a4FRM8DIRF:
9377 {
9378 tilerows = 2;
9379 basetile = n_frame_n_dir(4,8,f4);
9380
9381 if(clk2>0) //stopped to fire
9382 {
9383 tile+=40;
9384
9385 if(clk2<17) //firing
9386 {
9387 tile+=40;
9388 }
9389 }
9390 }
9391 break;
9392
9393 case a4FRM8DIRB:
9394 case a4FRM8DIRFB:
9395 {
9396 tilerows = 2;
9397 tiledir_big(dir,false);
9398 tile+=2*f4;
9399 if(clk2>0 && anim == a4FRM8DIRFB) //stopped to fire
9400 {
9401 tile+=80;
9402
9403 if(clk2<17) //firing
9404 {
9405 tile+=80;
9406 }
9407 }
9408 ignore_extend = true;
9409 }
9410 break;
9411
9412 case a4FRM4DIRB:
9413 case a4FRM4DIRFB:
9414 {
9415 tilerows = 2;
9416 tiledir_big(dir,true);
9417 tile+=2*f4;
9418 if(clk2>0 && anim == a4FRM4DIRFB) //stopped to fire
9419 {
9420 tile+=40;
9421
9422 if(clk2<17) //firing
9423 {
9424 tile+=40;
9425 }
9426 }
9427 ignore_extend = true;
9428 }
9429 break;
9430
9431 case aOCTO:
9432 {
9433
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1711 times.
✓ Branch 4 taken 1371 times.
4371 switch(dir)
9434 {
9435 case up:
9436 907 flip = 2;
9437 907 break;
9438
9439 case down:
9440 382 flip = 0;
9441 382 break;
9442
9443 case left:
9444 1711 flip = 0;
9445 1711 tile += 2;
9446 1711 break;
9447
9448 case right:
9449 1371 flip = 1;
9450 1371 tile += 2;
9451 1371 break;
9452 }
9453
9454 4371 tile+=f2;
9455 }
9456 4371 break;
9457
9458 case aWALK:
9459 {
9460
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 366 times.
✓ Branch 2 taken 548 times.
✓ Branch 3 taken 562 times.
✓ Branch 4 taken 48 times.
1524 switch(dir)
9461 {
9462 case up:
9463 366 tile+=3;
9464 366 flip = f2;
9465 366 break;
9466
9467 case down:
9468 548 tile+=2;
9469 548 flip = f2;
9470 548 break;
9471
9472 case left:
9473 562 flip=1;
9474 562 tile += f2;
9475 562 break;
9476
9477 case right:
9478 48 flip=0;
9479 48 tile += f2;
9480 48 break;
9481 }
9482 }
9483 1524 break;
9484
9485 case aDWALK:
9486 {
9487 if((get_bit(quest_rules,qr_BRKNSHLDTILES)) && (dummy_bool[1]==true))
9488 {
9489 tile=s_tile;
9490 basetile = s_tile;
9491 }
9492
9493 switch(dir)
9494 {
9495 case up:
9496 tile+=2;
9497 flip=f2;
9498 break;
9499
9500 case down:
9501 flip=0;
9502 tile+=(1-f2);
9503 break;
9504
9505 case left:
9506 flip=1;
9507 tile+=(3+f2);
9508 break;
9509
9510 case right:
9511 flip=0;
9512 tile+=(3+f2);
9513 break;
9514 }
9515 }
9516 break;
9517
9518 case aTEK:
9519 {
9520
2/2
✓ Branch 0 taken 2004 times.
✓ Branch 1 taken 365 times.
2369 if(misc==0)
9521 {
9522 365 tile += f2;
9523 365 }
9524
2/2
✓ Branch 0 taken 1045 times.
✓ Branch 1 taken 959 times.
2004 else if(misc!=1)
9525 {
9526 959 ++tile;
9527 959 }
9528 }
9529 2369 break;
9530
9531 case aNEWTEK:
9532 {
9533 if(step<0) //up
9534 {
9535 switch(clk3)
9536 {
9537 case left:
9538 flip=0;
9539 tile+=20;
9540 break;
9541
9542 case right:
9543 flip=0;
9544 tile+=24;
9545 break;
9546 }
9547 }
9548 else if(step==0)
9549 {
9550 switch(clk3)
9551 {
9552 case left:
9553 flip=0;
9554 tile+=8;
9555 break;
9556
9557 case right:
9558 flip=0;
9559 tile+=12;
9560 break;
9561 }
9562 } //down
9563 else
9564 {
9565 switch(clk3)
9566 {
9567 case left:
9568 flip=0;
9569 tile+=28;
9570 break;
9571
9572 case right:
9573 flip=0;
9574 tile+=32;
9575 break;
9576 }
9577 }
9578
9579 if(misc==0)
9580 {
9581 tile+=f4;
9582 }
9583 else if(misc!=1)
9584 {
9585 tile+=2;
9586 }
9587 }
9588 break;
9589
9590 case aARMOS:
9591 {
9592 if(!fading)
9593 {
9594 tile += fx;
9595
9596 if(dir==up)
9597 tile += 2;
9598 }
9599 }
9600 break;
9601
9602 case aARMOS4:
9603 {
9604 switch(dir)
9605 {
9606 case up:
9607 flip=0;
9608 break;
9609
9610 case down:
9611 flip=0;
9612 tile+=4;
9613 break;
9614
9615 case left:
9616 flip=0;
9617 tile+=8;
9618 break;
9619
9620 case right:
9621 flip=0;
9622 tile+=12;
9623 break;
9624 }
9625
9626 if(!fading)
9627 {
9628 tile+=f4;
9629 }
9630 }
9631 break;
9632
9633 case aGHINI:
9634 {
9635 switch(dir)
9636 {
9637 case 8:
9638 case 9:
9639 case up:
9640 ++tile;
9641 flip=0;
9642 break;
9643
9644 case 15:
9645 ++tile;
9646 flip=1;
9647 break;
9648
9649 case 10:
9650 case 11:
9651 case right:
9652 flip=1;
9653 break;
9654
9655 default:
9656 flip=0;
9657 break;
9658 }
9659 }
9660 break;
9661
9662 case a2FRMPOS:
9663 {
9664 3846 tile+=posframe;
9665 }
9666 3846 break;
9667
9668 case a4FRMPOS4DIR:
9669 {
9670 basetile = n_frame_n_dir(4,4,0);
9671 // tile+=f2;
9672 tile+=posframe;
9673 }
9674 break;
9675
9676 case a4FRMPOS4DIRF:
9677 {
9678 basetile = n_frame_n_dir(4,4,0);
9679
9680 if(clk2>0) //stopped to fire
9681 {
9682 tile+=20;
9683
9684 if(clk2<17) //firing
9685 {
9686 tile+=20;
9687 }
9688 }
9689
9690 // tile+=f2;
9691 tile+=posframe;
9692 }
9693 break;
9694
9695 case a4FRMPOS8DIR:
9696 {
9697 tilerows = 2;
9698 int32_t n = tile;
9699 basetile = n_frame_n_dir(4,8,0);
9700 // tile+=f2;
9701 tile+=posframe;
9702 }
9703 break;
9704
9705 case a4FRMPOS8DIRF:
9706 {
9707 tilerows = 2;
9708 basetile = n_frame_n_dir(4,8,0);
9709
9710 if(clk2>0) //stopped to fire
9711 {
9712 tile+=40;
9713
9714 if(clk2<17) //firing
9715 {
9716 tile+=40;
9717 }
9718 }
9719
9720 tile+=posframe;
9721 }
9722 break;
9723
9724 case aNEWLEV:
9725 {
9726 tiledir(dir,true);
9727
9728 switch(misc)
9729 {
9730 case -1:
9731 case 0:
9732 return;
9733
9734 case 1:
9735
9736 // case 5: cs = d->misc2; break;
9737 case 5:
9738 cs = dmisc2;
9739 break;
9740
9741 case 2:
9742 case 4:
9743 tile += 20;
9744 break;
9745
9746 case 3:
9747 tile += 40;
9748 break;
9749 }
9750
9751 tile+=f4;
9752 }
9753 break;
9754
9755 case aLEV:
9756 {
9757 721 f4 = ((clk/5)&1);
9758
9759
4/5
✓ Branch 0 taken 427 times.
✓ Branch 1 taken 51 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 219 times.
721 switch(misc)
9760 {
9761 case -1:
9762 case 0:
9763 427 return;
9764
9765 case 1:
9766
9767 // case 5: tile += (f2) ? 1 : 0; cs = d->misc2; break;
9768 case 5:
9769 51 tile += (f2) ? 1 : 0;
9770 51 cs = dmisc2;
9771 51 break;
9772
9773 case 2:
9774 case 4:
9775 24 tile += 2;
9776 24 break;
9777
9778 case 3:
9779 219 tile += (f4) ? 4 : 3;
9780 219 break;
9781 }
9782 }
9783 294 break;
9784
9785 case aWALLM:
9786 {
9787
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4548 times.
4548 if(!dummy_bool[1])
9788 {
9789 4548 tile += f2;
9790 4548 }
9791 }
9792 4548 break;
9793
9794 case aNEWWALLM:
9795 {
9796 int32_t tempdir=0;
9797
9798 switch(misc)
9799 {
9800 case 1:
9801 case 2:
9802 tempdir=clk3;
9803 break;
9804
9805 case 3:
9806 case 4:
9807 case 5:
9808 tempdir=dir;
9809 break;
9810
9811 case 6:
9812 case 7:
9813 tempdir=clk3^1;
9814 break;
9815 }
9816
9817 tiledir(tempdir,true);
9818
9819 if(!dummy_bool[1])
9820 {
9821 tile+=f4;
9822 }
9823 }
9824 break;
9825
9826 case a4FRMNODIR:
9827 {
9828 tile+=f4;
9829 }
9830 break;
9831
9832 } // switch(d->anim)
9833
9834 // flashing
9835 // if(d->flags2 & guy_flashing)
9836
1/2
✓ Branch 0 taken 53734 times.
✗ Branch 1 not taken.
53734 if(flags2 & guy_flashing)
9837 {
9838 cs = (frame&3) + 6;
9839 }
9840
9841
1/2
✓ Branch 0 taken 53734 times.
✗ Branch 1 not taken.
53734 if(flags2&guy_transparent)
9842 {
9843 drawstyle=1;
9844 }
9845
9846 53734 int32_t change = tile-basetile;
9847
9848
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 53734 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
53734 if(extend > 2 && (!ignore_extend || get_bit(quest_rules, qr_BROKEN_BIG_ENEMY_ANIMATION)))
9849 {
9850 if(basetile/TILES_PER_ROW==(basetile+((txsz*change)/tilerows))/TILES_PER_ROW)
9851 {
9852 tile=basetile+txsz*change;
9853 }
9854 else
9855 {
9856 tile=basetile+(txsz*change)+((tysz-1)*TILES_PER_ROW)*(((basetile+txsz*change)/TILES_PER_ROW)-(basetile/TILES_PER_ROW));
9857 }
9858 }
9859 else
9860 {
9861 53734 tile=basetile+change;
9862 }
9863 54161 }
9864
9865 28 int32_t wpnsfx(int32_t wpn)
9866 {
9867
2/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19 times.
28 switch(wpn)
9868 {
9869 case ewFireTrail:
9870 case ewFlame:
9871 case ewFlame2Trail:
9872 case ewFlame2:
9873 return WAV_FIRE;
9874
9875 case ewWind:
9876 case ewMagic:
9877 return WAV_WAND;
9878
9879 case ewIce:
9880 return WAV_ZN1ICE;
9881
9882 case ewRock:
9883
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if(get_bit(quest_rules,qr_MORESOUNDS)) return WAV_ZN1ROCK;
9884 19 break;
9885
9886 case ewFireball2:
9887 case ewFireball:
9888
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if(get_bit(quest_rules,qr_MORESOUNDS)) return WAV_ZN1FIREBALL;
9889 9 }
9890
9891 28 return -1;
9892 28 }
9893
9894 104988 int32_t enemy::run_script(int32_t mode)
9895 {
9896
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 104988 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
104988 if(switch_hooked && !get_bit(quest_rules, qr_SWITCHOBJ_RUN_SCRIPT)) return RUNSCRIPT_OK;
9897
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 104988 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
104988 if (script <= 0 || !doscript || FFCore.getQuestHeaderInfo(vZelda) < 0x255 || FFCore.system_suspend[susptNPCSCRIPTS])
9898 104988 return RUNSCRIPT_OK;
9899 int32_t ret = RUNSCRIPT_OK;
9900 alloc_scriptmem();
9901 switch(mode)
9902 {
9903 case MODE_NORMAL:
9904 return ZScriptVersion::RunScript(SCRIPT_NPC, script, getUID());
9905 case MODE_WAITDRAW:
9906 if(waitdraw)
9907 {
9908 ret = ZScriptVersion::RunScript(SCRIPT_NPC, script, getUID());
9909 waitdraw = 0;
9910 }
9911 break;
9912 }
9913 return ret;
9914 104988 }
9915
9916 /********************************/
9917 /********* Guy Class **********/
9918 /********************************/
9919
9920 // good guys, fires, fairy, and other non-enemies
9921 // based on enemy class b/c guys in dungeons act sort of like enemies
9922 // also easier to manage all the guys this way
9923 36 guy::guy(zfix X,zfix Y,int32_t Id,int32_t Clk,bool mg) : enemy(X,Y,Id,Clk)
9924 36 {
9925 12 mainguy=mg;
9926 12 canfreeze=false;
9927 12 dir=down;
9928
3/6
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
9929 12 hxofs=2;
9930 12 hzsz=8;
9931 12 hxsz=12;
9932 12 hysz=17;
9933
9934
8/12
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
12 if(!superman && (!isdungeon() || id==gFAIRY || id==gFIRE || id==gZELDA))
9935 {
9936 11 superman = 1;
9937 11 hxofs=1000;
9938 11 }
9939 24 }
9940
9941 4936 bool guy::animate(int32_t index)
9942 {
9943
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4936 times.
4936 if(switch_hooked) return enemy::animate(index);
9944
6/6
✓ Branch 0 taken 1376 times.
✓ Branch 1 taken 3560 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 1368 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4 times.
4936 if(mainguy && clk==0 && misc==0)
9945 {
9946 4 setupscreen();
9947 4 misc = 1;
9948 4 }
9949
9950
4/4
✓ Branch 0 taken 1376 times.
✓ Branch 1 taken 3560 times.
✓ Branch 2 taken 1373 times.
✓ Branch 3 taken 3 times.
4936 if(mainguy && fadeclk==0)
9951 3 return true;
9952
9953 4933 hp=256; // good guys never die...
9954
9955
4/4
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 4900 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 1 times.
4933 if(hclk && !clk2)
9956 {
9957 // but if they get hit...
9958 1 ++clk2; // only do this once
9959
9960
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(!get_bit(quest_rules,qr_NOGUYFIRES))
9961 {
9962 1 addenemy(BSZ?64:72,68,eSHOOTFBALL,0);
9963 1 addenemy(BSZ?176:168,68,eSHOOTFBALL,0);
9964 1 }
9965 1 }
9966
9967 4933 return enemy::animate(index);
9968 4936 }
9969
9970 4936 void guy::draw(BITMAP *dest)
9971 {
9972 4936 update_enemy_frame();
9973
9974
6/6
✓ Branch 0 taken 1376 times.
✓ Branch 1 taken 3560 times.
✓ Branch 2 taken 198 times.
✓ Branch 3 taken 1178 times.
✓ Branch 4 taken 99 times.
✓ Branch 5 taken 99 times.
4936 if(!mainguy || fadeclk<0 || fadeclk&1)
9975 4837 enemy::draw(dest);
9976 4936 }
9977
9978 /*******************************/
9979 /********* Enemies *********/
9980 /*******************************/
9981
9982 eFire::eFire(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
9983 {
9984 clk4=0;
9985 shield= (flags&(inv_left | inv_right | inv_back |inv_front)) != 0;
9986 // Spawn type
9987 if(flags & guy_fadeflicker)
9988 {
9989 clk=0;
9990 superman = 1;
9991 fading=fade_flicker;
9992 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
9993 dir=down;
9994
9995 if(!canmove(down,(zfix)8,spw_none,false))
9996 clk3=int32_t(13.0/step);
9997 }
9998 else if(flags & guy_fadeinstant)
9999 {
10000 clk=0;
10001 }
10002 SIZEflags = d->SIZEflags;
10003 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10004 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10005 // al_trace("Enemy txsz:%i\n", txsz);
10006 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10007 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10008 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10009 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10010 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10011 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10012 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10013 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10014 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10015 {
10016 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10017 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10018 }
10019
10020 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) d->zofs = (int32_t)zofs;
10021 }
10022
10023 bool eFire::animate(int32_t index)
10024 {
10025 if(switch_hooked) return enemy::animate(index);
10026 if(fallclk||drownclk) return enemy::animate(index);
10027 if(fading)
10028 {
10029 if(++clk4 > 60)
10030 {
10031 clk4=0;
10032 superman=0;
10033 fading=0;
10034
10035 if(flags2&cmbflag_armos && z==0 && fakez==0)
10036 removearmos(x,y,ffcactivated);
10037
10038 clk2=0;
10039
10040 if(!canmove(down,(zfix)8,spw_none,false))
10041 {
10042 dir=0;
10043 y = y.getInt() & 0xF0;
10044 }
10045
10046 return Dead(index);
10047 }
10048 else if(flags2&cmbflag_armos && z==0 && fakez==0 && clk==0)
10049 removearmos(x,y,ffcactivated);
10050 }
10051
10052 return enemy::animate(index);
10053 }
10054
10055 void eFire::draw(BITMAP *dest)
10056 {
10057 update_enemy_frame();
10058 enemy::draw(dest);
10059 }
10060
10061 int32_t eFire::takehit(weapon *w)
10062 {
10063 int32_t wpnId = w->id;
10064 int32_t wpnDir = w->dir;
10065
10066 if(wpnId==wHammer && shield && (flags & guy_bkshield)
10067 && ((flags&inv_front && wpnDir==(dir^down)) || (flags&inv_back && wpnDir==(dir^up))
10068 || (flags&inv_left && wpnDir==(dir^left)) || (flags&inv_right && wpnDir==(dir^right))))
10069 {
10070 shield = false;
10071 flags &= ~(inv_left|inv_right|inv_back|inv_front);
10072
10073 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10074 o_tile=s_tile;
10075 }
10076
10077 int32_t ret = enemy::takehit(w);
10078 return ret;
10079 }
10080
10081 void eFire::break_shield()
10082 {
10083 if(!shield)
10084 return;
10085
10086 flags&=~(inv_front | inv_back | inv_left | inv_right);
10087 shield=false;
10088
10089 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10090 o_tile=s_tile;
10091 }
10092
10093 eOther::eOther(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10094 {
10095 //zprint2("npct other::other\n");
10096 clk4=0;
10097 shield= (flags&(inv_left | inv_right | inv_back |inv_front)) != 0;
10098
10099 // Spawn type
10100 if(flags & guy_fadeflicker)
10101 {
10102 clk=0;
10103 superman = 1;
10104 fading=fade_flicker;
10105 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
10106 dir=down;
10107
10108 if(!canmove(down,(zfix)8,spw_none,false))
10109 clk3=int32_t(13.0/step);
10110 }
10111 else if(flags & guy_fadeinstant)
10112 {
10113 clk=0;
10114 }
10115 SIZEflags = d->SIZEflags;
10116 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10117 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10118 // al_trace("Enemy txsz:%i\n", txsz);
10119 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10120 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10121 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10122 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10123 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10124 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10125 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10126 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10127 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10128 {
10129 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10130 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10131 }
10132
10133 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10134 }
10135
10136 bool eOther::animate(int32_t index)
10137 {
10138 if(switch_hooked) return enemy::animate(index);
10139 if(fallclk||drownclk) return enemy::animate(index);
10140 //zprint2("npct other::animate\n");
10141 if(fading)
10142 {
10143 if(++clk4 > 60)
10144 {
10145 clk4=0;
10146 superman=0;
10147 fading=0;
10148
10149 if(flags2&cmbflag_armos && z==0 && fakez==0)
10150 removearmos(x,y,ffcactivated);
10151
10152 clk2=0;
10153
10154 if(!canmove(down,(zfix)8,spw_none,false))
10155 {
10156 dir=0;
10157 y = y.getInt() & 0xF0;
10158 }
10159
10160 return Dead(index);
10161 }
10162 else if(flags2&cmbflag_armos && z==0 && fakez==0 && clk==0)
10163 removearmos(x,y,ffcactivated);
10164 }
10165
10166 return enemy::animate(index);
10167 }
10168
10169 void eOther::draw(BITMAP *dest)
10170 {
10171 update_enemy_frame();
10172 enemy::draw(dest);
10173 }
10174
10175 int32_t eOther::takehit(weapon *w)
10176 {
10177 int32_t wpnId = w->id;
10178 int32_t wpnDir = w->dir;
10179
10180 if(wpnId==wHammer && shield && (flags & guy_bkshield)
10181 && ((flags&inv_front && wpnDir==(dir^down)) || (flags&inv_back && wpnDir==(dir^up))
10182 || (flags&inv_left && wpnDir==(dir^left)) || (flags&inv_right && wpnDir==(dir^right))))
10183 {
10184 shield = false;
10185 flags &= ~(inv_left|inv_right|inv_back|inv_front);
10186
10187 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10188 o_tile=s_tile;
10189 }
10190
10191 int32_t ret = enemy::takehit(w);
10192 return ret;
10193 }
10194
10195 void eOther::break_shield()
10196 {
10197 if(!shield)
10198 return;
10199
10200 flags&=~(inv_front | inv_back | inv_left | inv_right);
10201 shield=false;
10202
10203 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10204 o_tile=s_tile;
10205 }
10206
10207
10208 eScript::eScript(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10209 {
10210 clk4=0;
10211 shield= (flags&(inv_left | inv_right | inv_back |inv_front)) != 0;
10212
10213 // Spawn type
10214 if(flags & guy_fadeflicker)
10215 {
10216 clk=0;
10217 superman = 1;
10218 fading=fade_flicker;
10219 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
10220 dir=down;
10221
10222 if(!canmove(down,(zfix)8,spw_none,false))
10223 clk3=int32_t(13.0/step);
10224 }
10225 else if(flags & guy_fadeinstant)
10226 {
10227 clk=0;
10228 }
10229 SIZEflags = d->SIZEflags;
10230 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10231 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10232 // al_trace("Enemy txsz:%i\n", txsz);
10233 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10234 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10235 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10236 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10237 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10238 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10239 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10240 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10241 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10242 {
10243 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10244 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10245 }
10246
10247 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10248 }
10249
10250 bool eScript::animate(int32_t index)
10251 {
10252 if(switch_hooked) return enemy::animate(index);
10253 if(fallclk||drownclk) return enemy::animate(index);
10254 if(fading)
10255 {
10256 if(++clk4 > 60)
10257 {
10258 clk4=0;
10259 superman=0;
10260 fading=0;
10261
10262 if(flags2&cmbflag_armos && z==0 && fakez==0)
10263 removearmos(x,y,ffcactivated);
10264
10265 clk2=0;
10266
10267 if(!canmove(down,(zfix)8,spw_none,false))
10268 {
10269 dir=0;
10270 y = y.getInt() & 0xF0;
10271 }
10272
10273 return Dead(index);
10274 }
10275 else if(flags2&cmbflag_armos && z==0 && fakez==0 && clk==0)
10276 removearmos(x,y,ffcactivated);
10277 }
10278
10279 return enemy::animate(index);
10280 }
10281
10282 void eScript::draw(BITMAP *dest)
10283 {
10284 update_enemy_frame();
10285 enemy::draw(dest);
10286 }
10287
10288 int32_t eScript::takehit(weapon *w)
10289 {
10290 int32_t wpnId = w->id;
10291 int32_t wpnDir = w->dir;
10292
10293 if(wpnId==wHammer && shield && (flags & guy_bkshield)
10294 && ((flags&inv_front && wpnDir==(dir^down)) || (flags&inv_back && wpnDir==(dir^up))
10295 || (flags&inv_left && wpnDir==(dir^left)) || (flags&inv_right && wpnDir==(dir^right))))
10296 {
10297 shield = false;
10298 flags &= ~(inv_left|inv_right|inv_back|inv_front);
10299
10300 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10301 o_tile=s_tile;
10302 }
10303
10304 int32_t ret = enemy::takehit(w);
10305 return ret;
10306 }
10307
10308 void eScript::break_shield()
10309 {
10310 if(!shield)
10311 return;
10312
10313 flags&=~(inv_front | inv_back | inv_left | inv_right);
10314 shield=false;
10315
10316 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10317 o_tile=s_tile;
10318 }
10319
10320
10321 eFriendly::eFriendly(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10322 {
10323 clk4=0;
10324 hyofs = -32768; //No hitbox initially.
10325 shield= (flags&(inv_left | inv_right | inv_back |inv_front)) != 0;
10326
10327 // Spawn type
10328 if(flags & guy_fadeflicker)
10329 {
10330 clk=0;
10331 superman = 1;
10332 fading=fade_flicker;
10333 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
10334 dir=down;
10335
10336 if(!canmove(down,(zfix)8,spw_none,false))
10337 clk3=int32_t(13.0/step);
10338 }
10339 else if(flags & guy_fadeinstant)
10340 {
10341 clk=0;
10342 }
10343 SIZEflags = d->SIZEflags;
10344 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10345 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10346 // al_trace("Enemy txsz:%i\n", txsz);
10347 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10348 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10349 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10350 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10351 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10352 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10353 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10354 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10355 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10356 {
10357 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10358 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10359 }
10360
10361 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10362 }
10363
10364 bool eFriendly::animate(int32_t index)
10365 {
10366 if(switch_hooked) return enemy::animate(index);
10367 if(fallclk||drownclk) return enemy::animate(index);
10368 if(fading)
10369 {
10370 if(++clk4 > 60)
10371 {
10372 clk4=0;
10373 superman=0;
10374 fading=0;
10375
10376 if(flags2&cmbflag_armos && z==0 && fakez==0)
10377 removearmos(x,y,ffcactivated);
10378
10379 clk2=0;
10380
10381 if(!canmove(down,(zfix)8,spw_none,false))
10382 {
10383 dir=0;
10384 y = y.getInt() & 0xF0;
10385 }
10386
10387 return Dead(index);
10388 }
10389 else if(flags2&cmbflag_armos && z==0 && fakez==0 && clk==0)
10390 removearmos(x,y,ffcactivated);
10391 }
10392
10393 return enemy::animate(index);
10394 }
10395
10396 void eFriendly::draw(BITMAP *dest)
10397 {
10398 update_enemy_frame();
10399 enemy::draw(dest);
10400 }
10401
10402 int32_t eFriendly::takehit(weapon *w)
10403 {
10404 int32_t wpnId = w->id;
10405 int32_t wpnDir = w->dir;
10406
10407 if(wpnId==wHammer && shield && (flags & guy_bkshield)
10408 && ((flags&inv_front && wpnDir==(dir^down)) || (flags&inv_back && wpnDir==(dir^up))
10409 || (flags&inv_left && wpnDir==(dir^left)) || (flags&inv_right && wpnDir==(dir^right))))
10410 {
10411 shield = false;
10412 flags &= ~(inv_left|inv_right|inv_back|inv_front);
10413
10414 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10415 o_tile=s_tile;
10416 }
10417
10418 int32_t ret = enemy::takehit(w);
10419 return ret;
10420 }
10421
10422 void eFriendly::break_shield()
10423 {
10424 if(!shield)
10425 return;
10426
10427 flags&=~(inv_front | inv_back | inv_left | inv_right);
10428 shield=false;
10429
10430 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10431 o_tile=s_tile;
10432 }
10433
10434
10435 366 void enemy::removearmos(int32_t ax,int32_t ay, word ffcactive)
10436 {
10437
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 366 times.
366 if (ffcactive)
10438 {
10439 removearmosffc(ffcactive-1);
10440 return;
10441 }
10442
1/2
✓ Branch 0 taken 366 times.
✗ Branch 1 not taken.
366 if(did_armos)
10443 {
10444 366 return;
10445 }
10446
10447 did_armos=true;
10448 ax&=0xF0;
10449 ay&=0xF0;
10450 int32_t cd = (ax>>4)+ay;
10451 int32_t f = MAPFLAG(ax,ay);
10452 int32_t f2 = MAPCOMBOFLAG(ax,ay);
10453
10454 if(combobuf[tmpscr->data[cd]].type!=cARMOS)
10455 {
10456 return;
10457 }
10458
10459 tmpscr->data[cd] = tmpscr->undercombo;
10460 tmpscr->cset[cd] = tmpscr->undercset;
10461 tmpscr->sflag[cd] = 0;
10462
10463 if(f == mfARMOS_SECRET || f2 == mfARMOS_SECRET)
10464 {
10465 tmpscr->data[cd] = tmpscr->secretcombo[sSTAIRS];
10466 tmpscr->cset[cd] = tmpscr->secretcset[sSTAIRS];
10467 tmpscr->sflag[cd]=tmpscr->secretflag[sSTAIRS];
10468 sfx(tmpscr->secretsfx);
10469 }
10470
10471 if(f == mfARMOS_ITEM || f2 == mfARMOS_ITEM)
10472 {
10473 if(!getmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM) || (tmpscr->flags9&fBELOWRETURN))
10474 {
10475 additem(ax,ay,tmpscr->catchall, (ipONETIME2 + ipBIGRANGE) | ((tmpscr->flags3&fHOLDITEM) ? ipHOLDUP : 0) | ((tmpscr->flags8&fITEMSECRET) ? ipSECRETS : 0));
10476 sfx(tmpscr->secretsfx);
10477 }
10478 }
10479
10480 putcombo(scrollbuf,ax,ay,tmpscr->data[cd],tmpscr->cset[cd]);
10481 366 }
10482
10483 void enemy::removearmosffc(int32_t pos)
10484 {
10485 if(did_armos)
10486 {
10487 return;
10488 }
10489
10490 did_armos=true;
10491 ffcdata& ffc = tmpscr->ffcs[pos];
10492 newcombo const& cmb = combobuf[ffc.getData()];
10493 int32_t f2 = cmb.flag;
10494
10495 if(cmb.type!=cARMOS)
10496 {
10497 return;
10498 }
10499
10500 ffc.setData(tmpscr->undercombo);
10501 ffc.cset = tmpscr->undercset;
10502
10503 if(f2 == mfARMOS_SECRET)
10504 {
10505 ffc.setData(tmpscr->secretcombo[sSTAIRS]);
10506 ffc.cset = tmpscr->secretcset[sSTAIRS];
10507 sfx(tmpscr->secretsfx);
10508 }
10509
10510 if(f2 == mfARMOS_ITEM)
10511 {
10512 if(!getmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM) || (tmpscr->flags9&fBELOWRETURN))
10513 {
10514 additem(ffc.x,ffc.y,tmpscr->catchall, (ipONETIME2 + ipBIGRANGE) | ((tmpscr->flags3&fHOLDITEM) ? ipHOLDUP : 0) | ((tmpscr->flags8&fITEMSECRET) ? ipSECRETS : 0));
10515 sfx(tmpscr->secretsfx);
10516 }
10517 }
10518
10519 putcombo(scrollbuf,ffc.x,ffc.y,ffc.getData(),ffc.cset);
10520 }
10521
10522
10523 eGhini::eGhini(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10524 {
10525 fading=fade_flicker;
10526 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
10527 dir=12;
10528 movestatus=1;
10529 step=0;
10530 clk=0;
10531 clk4=0;
10532 SIZEflags = d->SIZEflags;
10533 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10534 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10535 // al_trace("Enemy txsz:%i\n", txsz);
10536 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10537 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10538 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10539 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10540 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10541 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10542 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10543 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10544 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10545 {
10546 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10547 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10548 }
10549
10550 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10551 }
10552
10553 bool eGhini::animate(int32_t index)
10554 {
10555 if(switch_hooked) return enemy::animate(index);
10556 if(fallclk||drownclk) return enemy::animate(index);
10557 if(dying)
10558 return Dead(index);
10559
10560 if(dmisc1)
10561 {
10562 if(misc)
10563 {
10564 if(clk4>160)
10565 misc=2;
10566
10567 floater_walk((misc==1)?0:rate,hrate,zslongToFix(dstep*100),zslongToFix(dstep*10),10,dmisc16,dmisc17); //120,10);
10568 removearmos(x,y,ffcactivated);
10569 }
10570 else if(clk4>=60)
10571 {
10572 misc=1;
10573 clk3=32;
10574 fading=0;
10575 if (ffcactivated > 0)
10576 {
10577 guygridffc[ffcactivated-1] = 0;
10578 removearmosffc(ffcactivated-1);
10579 }
10580 else
10581 {
10582 guygrid[(int32_t(y)&0xF0)+(int32_t(x)>>4)]=0;
10583 removearmos(x,y);
10584 }
10585 }
10586 }
10587
10588 clk4++;
10589
10590 return enemy::animate(index);
10591 }
10592
10593 void eGhini::draw(BITMAP *dest)
10594 {
10595 update_enemy_frame();
10596 enemy::draw(dest);
10597 }
10598
10599 void eGhini::kickbucket()
10600 {
10601 hp=-1000; // don't call death_sfx()
10602 }
10603
10604
3/6
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
32 eTektite::eTektite(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10605 24 {
10606
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 old_y=y;
10607 8 dir=down;
10608 8 misc=1;
10609 8 clk=-15;
10610
10611
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if(!BSZ)
10612
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 clk*=zc_oldrand()%3+1;
10613
10614 // avoid divide by 0 errors
10615
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if(dmisc1 == 0)
10616 dmisc1 = 24;
10617
10618
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if(dmisc2 == 0)
10619 dmisc2 = 3;
10620
10621 //nets+760;
10622 8 SIZEflags = d->SIZEflags;
10623
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
8 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10624 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10625 // al_trace("Enemy txsz:%i\n", txsz);
10626
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
8 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10627
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10628
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10629
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10630
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10631
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10632 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10633
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10634
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10635 {
10636 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10637 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10638 }
10639
10640
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10641 16 }
10642
10643 2368 bool eTektite::animate(int32_t index)
10644 {
10645
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2368 times.
2368 if(switch_hooked) return enemy::animate(index);
10646
2/4
✓ Branch 0 taken 2368 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2368 times.
2368 if(fallclk||drownclk) return enemy::animate(index);
10647
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 2314 times.
2368 if(dying)
10648 54 return Dead(index);
10649
10650
2/2
✓ Branch 0 taken 2263 times.
✓ Branch 1 taken 51 times.
2314 if(clk==0)
10651 {
10652 51 removearmos(x,y,ffcactivated);
10653 51 }
10654
10655
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 if(get_bit(quest_rules,qr_ENEMIESZAXIS))
10656 {
10657 y=floor_y;
10658 }
10659
10660
5/10
✓ Branch 0 taken 2044 times.
✓ Branch 1 taken 270 times.
✓ Branch 2 taken 2044 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2044 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2044 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
2314 if(clk>=0 && !stunclk && !frozenclock && (!watch || misc==0))
10661 {
10662
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 365 times.
✓ Branch 2 taken 756 times.
✓ Branch 3 taken 923 times.
2044 switch(misc)
10663 {
10664 case 0: // normal
10665
2/2
✓ Branch 0 taken 340 times.
✓ Branch 1 taken 25 times.
365 if(!(zc_oldrand()%dmisc1))
10666 {
10667 25 misc=1;
10668 25 clk2=32;
10669 25 }
10670
10671 365 break;
10672
10673 case 1: // waiting to pounce
10674
2/2
✓ Branch 0 taken 717 times.
✓ Branch 1 taken 39 times.
756 if(--clk2<=0)
10675 {
10676 39 int32_t r=zc_oldrand();
10677 39 misc=2;
10678 39 step=0-(zslongToFix(dstep*100)); // initial speed
10679 39 clk3=(r&1)+2; // left or right
10680 39 clk2start=clk2=(r&31)+10; // flight time
10681
10682
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 1 times.
39 if(y<32) clk2+=2; // make them come down from top of screen
10683
10684
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 14 times.
39 if(y>112) clk2-=2; // make them go back up
10685
10686 39 cstart=c = 9-((r&31)>>3); // time before gravity kicks in
10687 39 }
10688
10689 756 break;
10690
10691 case 2: // in flight
10692 923 move(step);
10693
10694
2/2
✓ Branch 0 taken 432 times.
✓ Branch 1 taken 491 times.
923 if(step>0) //going down
10695 {
10696
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 432 times.
432 if(COMBOTYPE(x+8,y+16)==cNOJUMPZONE)
10697 {
10698 step=0-step;
10699 }
10700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 432 times.
432 else if(COMBOTYPE(x+8,y+16)==cNOENEMY)
10701 {
10702 step=0-step;
10703 }
10704
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 432 times.
432 else if(ispitfall(x+8,y+16))
10705 {
10706 step=0-step;
10707 }
10708
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 432 times.
432 else if(MAPFLAG(x+8,y+16)==mfNOENEMY)
10709 {
10710 step=0-step;
10711 }
10712
1/2
✓ Branch 0 taken 432 times.
✗ Branch 1 not taken.
432 else if(MAPCOMBOFLAG(x+8,y+16)==mfNOENEMY)
10713 {
10714 step=0-step;
10715 }
10716 432 }
10717
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 459 times.
491 else if(step<0)
10718 {
10719
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 459 times.
459 if(COMBOTYPE(x+8,y)==cNOJUMPZONE)
10720 {
10721 step=0-step;
10722 }
10723
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 459 times.
459 else if(COMBOTYPE(x+8,y)==cNOENEMY)
10724 {
10725 step=0-step;
10726 }
10727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 459 times.
459 else if(ispitfall(x+8,y))
10728 {
10729 step=0-step;
10730 }
10731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 459 times.
459 else if(MAPFLAG(x+8,y)==mfNOENEMY)
10732 {
10733 step=0-step;
10734 }
10735
1/2
✓ Branch 0 taken 459 times.
✗ Branch 1 not taken.
459 else if(MAPCOMBOFLAG(x+8,y)==mfNOENEMY)
10736 {
10737 step=0-step;
10738 }
10739 459 }
10740
10741
2/2
✓ Branch 0 taken 450 times.
✓ Branch 1 taken 473 times.
923 if(clk3==left)
10742 {
10743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 450 times.
450 if(COMBOTYPE(x,y+8)==cNOJUMPZONE)
10744 {
10745 clk3^=1;
10746 }
10747
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 450 times.
450 else if(COMBOTYPE(x,y+8)==cNOENEMY)
10748 {
10749 clk3^=1;
10750 }
10751
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 450 times.
450 else if(ispitfall(x,y+8))
10752 {
10753 clk3^=1;
10754 }
10755
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 450 times.
450 else if(MAPFLAG(x,y+8)==mfNOENEMY)
10756 {
10757 clk3^=1;
10758 }
10759
1/2
✓ Branch 0 taken 450 times.
✗ Branch 1 not taken.
450 else if(MAPCOMBOFLAG(x,y+8)==mfNOENEMY)
10760 {
10761 clk3^=1;
10762 }
10763 450 }
10764 else
10765 {
10766
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 473 times.
473 if(COMBOTYPE(x+16,y+8)==cNOJUMPZONE)
10767 {
10768 clk3^=1;
10769 }
10770
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 473 times.
473 else if(COMBOTYPE(x+16,y+8)==cNOENEMY)
10771 {
10772 clk3^=1;
10773 }
10774
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 473 times.
473 else if(ispitfall(x+16,y+8))
10775 {
10776 clk3^=1;
10777 }
10778
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 473 times.
473 else if(MAPFLAG(x+16,y+8)==mfNOENEMY)
10779 {
10780 clk3^=1;
10781 }
10782
1/2
✓ Branch 0 taken 473 times.
✗ Branch 1 not taken.
473 else if(MAPCOMBOFLAG(x+16,y+8)==mfNOENEMY)
10783 {
10784 clk3^=1;
10785 }
10786 }
10787
10788 923 --c;
10789
10790
4/4
✓ Branch 0 taken 285 times.
✓ Branch 1 taken 638 times.
✓ Branch 2 taken 597 times.
✓ Branch 3 taken 326 times.
923 if(c<0 && step<zslongToFix(dstep*100))
10791 {
10792 326 step+=zslongToFix(dmisc3*100);
10793 326 }
10794
10795 923 int32_t nb=get_bit(quest_rules,qr_NOBORDER) ? 16 : 0;
10796
10797
2/2
✓ Branch 0 taken 921 times.
✓ Branch 1 taken 2 times.
923 if(x<=16-nb) clk3=right;
10798
10799
1/2
✓ Branch 0 taken 923 times.
✗ Branch 1 not taken.
923 if(x>=224+nb) clk3=left;
10800
10801 923 x += (clk3==left) ? -1 : 1;
10802
10803
4/4
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 893 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 887 times.
923 if((--clk2<=0 && y>=16-nb) || y>=144+nb)
10804 {
10805
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
36 if(y>=144+nb && get_bit(quest_rules,qr_ENEMIESZAXIS))
10806 {
10807 step=0-step;
10808 y--;
10809 }
10810
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 10 times.
36 else if(zc_oldrand()%dmisc2) //land and wait
10811 {
10812 26 clk=misc=0;
10813 26 } //land and jump again
10814 else
10815 {
10816 10 misc=1;
10817 10 clk2=0;
10818 }
10819 36 }
10820
10821 923 break;
10822 } // switch
10823 2044 }
10824
10825
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2314 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2314 if(get_bit(quest_rules,qr_ENEMIESZAXIS) && misc==2)
10826 {
10827 if (moveflags & FLAG_USE_FAKE_Z)
10828 {
10829 int32_t tempy = floor_y;
10830 fakez=zc_max(0,zc_min(clk2start-clk2,clk2));
10831 floor_y = y;
10832 y=tempy-fakez;
10833 old_y = y;
10834 }
10835 else
10836 {
10837 int32_t tempy = floor_y;
10838 z=zc_max(0,zc_min(clk2start-clk2,clk2));
10839 floor_y = y;
10840 y=tempy-z;
10841 old_y = y;
10842 }
10843 }
10844
10845
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2314 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2314 if(stunclk && (clk&31)==1)
10846 clk=0;
10847
10848 2314 return enemy::animate(index);
10849 2368 }
10850
10851 void eTektite::drawshadow(BITMAP *dest,bool translucent)
10852 {
10853 if(z<1 && fakez<1 && get_bit(quest_rules,qr_ENEMIESZAXIS))
10854 return;
10855
10856 int32_t tempy=yofs;
10857 int32_t fdiv = frate/4;
10858 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
10859 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
10860 efrate:((clk>=(frate>>1))?1:0);
10861 flip = 0;
10862 shadowtile = wpnsbuf[spr_shadow].tile;
10863
10864 if(get_bit(quest_rules,qr_NEWENEMYTILES))
10865 {
10866 if(misc==0)
10867 {
10868 shadowtile+=f2;
10869 }
10870 else if(misc!=1)
10871 shadowtile+=2;
10872 }
10873 else
10874 {
10875 if(misc==0)
10876 {
10877 shadowtile += f2 ? 1 : 0;
10878 }
10879 else if(misc!=1)
10880 {
10881 ++shadowtile;
10882 }
10883 }
10884
10885 yofs+=8;
10886
10887 if(!get_bit(quest_rules,qr_ENEMIESZAXIS) && misc==2)
10888 {
10889 yofs+=zc_max(0,zc_min(clk2start-clk2,clk2));
10890 }
10891 if(!shadow_overpit(this))
10892 enemy::drawshadow(dest,translucent);
10893 yofs=tempy;
10894 }
10895
10896 2369 void eTektite::draw(BITMAP *dest)
10897 {
10898 2369 update_enemy_frame();
10899 2369 enemy::draw(dest);
10900 2369 }
10901
10902 eItemFairy::eItemFairy(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10903 {
10904 step=zslongToFix(guysbuf[id&0xFFF].step*100);
10905 superman=1;
10906 dir=8;
10907 hxofs=1000;
10908 mainguy=false;
10909 count_enemy=false;
10910 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10911 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10912 // al_trace("Enemy txsz:%i\n", txsz);
10913 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = tysz; if ( tysz > 1 ) extend = 3; }
10914 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = hxsz;
10915 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = hysz;
10916 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = hzsz;
10917 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = hxofs;
10918 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = hyofs;
10919 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10920 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)xofs;
10921 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10922 {
10923 yofs = (int32_t)yofs; //This seems to be setting to +48 or something with any value set?! -Z
10924 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10925 }
10926
10927 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
10928 }
10929
10930 bool eItemFairy::animate(int32_t index)
10931 {
10932 if(switch_hooked) return enemy::animate(index);
10933 if(dying)
10934 return Dead(index);
10935
10936 //if(clk>32)
10937 misc=1;
10938 bool w=watch;
10939 watch=false;
10940 variable_walk_8(misc?3:0,0,8,spw_floater);
10941 watch=w;
10942
10943 if(clk==0)
10944 {
10945 removearmos(x,y,ffcactivated);
10946 }
10947
10948 return enemy::animate(index);
10949 }
10950
10951 void eItemFairy::draw(BITMAP *dest)
10952 {
10953 //these are here to bypass compiler warnings about unused arguments
10954 dest=dest;
10955 }
10956
10957 ePeahat::ePeahat(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10958 {
10959 //floater_walk(int32_t rate,int32_t newclk,zfix ms,zfix ss,int32_t s,int32_t p, int32_t g)
10960 floater_walk(misc?rate:0, hrate, zslongToFix(dstep*100),zslongToFix(dstep*10), 10, dmisc16,dmisc17); // 80, 16);
10961 dir=8;
10962 movestatus=1;
10963 clk=0;
10964 step=0;
10965 //nets+720;
10966 SIZEflags = d->SIZEflags;
10967 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10968 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10969 // al_trace("Enemy txsz:%i\n", txsz);
10970 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10971 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10972 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10973 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10974 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10975 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10976 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10977 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10978 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10979 {
10980 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10981 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10982 }
10983
10984 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10985 }
10986
10987 bool ePeahat::animate(int32_t index)
10988 {
10989 if(switch_hooked) return enemy::animate(index);
10990 if(fallclk||drownclk) return enemy::animate(index);
10991 if(slide())
10992 {
10993 return false;
10994 }
10995
10996 if(dying)
10997 return Dead(index);
10998
10999 if(clk==0)
11000 {
11001 removearmos(x,y,ffcactivated);
11002 }
11003
11004 if(stunclk==0 && clk>96)
11005 misc=1;
11006
11007 if(!watch)
11008 floater_walk(misc?rate:0, hrate, zslongToFix(dstep*100),zslongToFix(dstep*10), 10, 80, 16);
11009
11010 if(get_bit(quest_rules,qr_ENEMIESZAXIS) && !(isSideViewGravity()))
11011 {
11012 if (moveflags & FLAG_USE_FAKE_Z) fakez=int32_t(step*1.1/((zslongToFix(dstep*10))*1.1));
11013 else z=int32_t(step*1.1/((zslongToFix(dstep*10))*1.1));
11014 }
11015
11016 if(watch && get_bit(quest_rules,qr_PEAHATCLOCKVULN))
11017 superman=0;
11018 else
11019 superman=(movestatus && !get_bit(quest_rules,qr_ENEMIESZAXIS)) ? 1 : 0;
11020 //stunclk=0; //Not sure what was going on here, or what was intended. Why was this set to 0? -Z
11021 if ( FFCore.getQuestHeaderInfo(vZelda) >= 0x250 )
11022 {
11023 if ( stunclk ) --stunclk;
11024 }
11025 else stunclk = 0; //Was probably this way in 2.10 quests. if not, then we never need to clear it. -Z
11026 //Pretty sure this was always an error. -Z ( 14FEB2019 )
11027
11028
11029 if(x<16) dir=right; //this is ugly, but so is moving or creating these guys with scripts.
11030
11031 return enemy::animate(index);
11032 }
11033
11034 void ePeahat::drawshadow(BITMAP *dest, bool translucent)
11035 {
11036 int32_t tempy=yofs;
11037 flip = 0;
11038 shadowtile = wpnsbuf[spr_shadow].tile+posframe;
11039
11040 if(!get_bit(quest_rules,qr_ENEMIESZAXIS))
11041 {
11042 yofs+=8;
11043 yofs+=int32_t(step/zslongToFix(dstep*10));
11044 }
11045 if(!shadow_overpit(this))
11046 enemy::drawshadow(dest,translucent);
11047 yofs=tempy;
11048 }
11049
11050 void ePeahat::draw(BITMAP *dest)
11051 {
11052 update_enemy_frame();
11053 enemy::draw(dest);
11054 }
11055
11056 int32_t ePeahat::takehit(weapon *w)
11057 {
11058 int32_t wpnId = w->id;
11059 int32_t enemyHitWeapon = w->parentitem;
11060
11061 if(dying || clk<0 || hclk>0)
11062 return 0;
11063
11064 if(superman && !(wpnId==wSBomb) // vulnerable to super bombs
11065 // fire boomerang, for nailing peahats
11066 && !(wpnId==wBrang && (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_brang))>0))
11067 return 0;
11068
11069 // Time for a kludge...
11070 int32_t s = superman;
11071 superman = 0;
11072 int32_t ret = enemy::takehit(w);
11073 superman = s;
11074
11075 // Anyway...
11076 if(stunclk == 160)
11077 {
11078 clk2=0;
11079 movestatus=0;
11080 misc=0;
11081 clk=0;
11082 step=0;
11083 }
11084
11085 return ret;
11086 }
11087
11088 // auomatically kill off enemy (for rooms with ringleaders)
11089 void ePeahat::kickbucket()
11090 {
11091 hp=-1000; // don't call death_sfx()
11092 }
11093
11094 12 eLeever::eLeever(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
11095 12 {
11096 // if(d->misc1==0) { misc=-1; clk-=16; } //Line of Sight leevers
11097
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(dmisc1==0)
11098 {
11099 4 misc=-1; //Line of Sight leevers
11100 4 clk-=16;
11101 4 }
11102 4 clk3 = 0;
11103 //nets+1460;
11104
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 temprule=(get_bit(quest_rules,qr_NEWENEMYTILES)) != 0;
11105 4 submerged = false;
11106 4 SIZEflags = d->SIZEflags;
11107
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
11108 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
11109 // al_trace("Enemy txsz:%i\n", txsz);
11110
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
11111
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
11112
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
11113
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
11114
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
11115
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
11116 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
11117
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
11118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
11119 {
11120 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
11121 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
11122 }
11123
11124
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
11125 8 }
11126
11127 bool eLeever::isSubmerged() const
11128 {
11129 Z_scripterrlog("misc is: %d\n", misc);
11130 return misc <= 0;
11131
11132 }
11133
11134 721 bool eLeever::animate(int32_t index)
11135 {
11136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 721 times.
721 if(switch_hooked) return enemy::animate(index);
11137
2/4
✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 721 times.
721 if(fallclk||drownclk)
11138 {
11139 return enemy::animate(index);
11140 }
11141
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 703 times.
721 if(dying)
11142 18 return Dead(index);
11143
11144
2/2
✓ Branch 0 taken 690 times.
✓ Branch 1 taken 13 times.
703 if(clk==0)
11145 {
11146 13 removearmos(x,y,ffcactivated);
11147 13 }
11148
11149
4/4
✓ Branch 0 taken 489 times.
✓ Branch 1 taken 214 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 474 times.
703 if(clk>=0 && !slide())
11150 {
11151 // switch(d->misc1)
11152
1/2
✓ Branch 0 taken 474 times.
✗ Branch 1 not taken.
474 switch(dmisc1)
11153 {
11154 case 0: //line of sight
11155 case 2:
11156
5/8
✗ Branch 0 not taken.
✓ Branch 1 taken 208 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 186 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
474 switch(misc) //is this leever active
11157 {
11158 case -1: //submerged
11159 {
11160
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 208 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
208 if (!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk)) misc = 0;
11161
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 208 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
208 if((dmisc1==2)&&(zc_oldrand()&255))
11162 {
11163 break;
11164 }
11165
11166 208 int32_t active=0;
11167
11168
2/2
✓ Branch 0 taken 1003 times.
✓ Branch 1 taken 208 times.
1211 for(int32_t i=0; i<guys.Count(); i++)
11169 {
11170
4/4
✓ Branch 0 taken 795 times.
✓ Branch 1 taken 208 times.
✓ Branch 2 taken 383 times.
✓ Branch 3 taken 412 times.
1003 if(guys.spr(i)->id==id && (((enemy*)guys.spr(i))->misc>=0))
11171 {
11172 412 ++active;
11173 412 }
11174 1003 }
11175
11176
2/2
✓ Branch 0 taken 205 times.
✓ Branch 1 taken 3 times.
208 if(active<((dmisc1==2)?1:2))
11177 {
11178 3 misc=0; //activate this one
11179 3 clk3=1; //This needs to be set so that it knows that it's being emerged of it's own will and not because it got stunned.
11180 3 }
11181 }
11182 208 break;
11183
11184 case 0:
11185 {
11186
11187
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
5 if (!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk))
11188 {
11189 misc=1;
11190 clk2=0;
11191 }
11192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 else if (clk3<=0)
11193 {
11194 misc = -1;
11195 break;
11196 }
11197 5 int32_t s=0;
11198
11199
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 5 times.
29 for(int32_t i=0; i<guys.Count(); i++)
11200 {
11201
4/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 2 times.
24 if(guys.spr(i)->id==id && ((enemy*)guys.spr(i))->misc==1)
11202 {
11203 2 ++s;
11204 2 }
11205 24 }
11206
11207
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 if(s>0)
11208 {
11209 2 break;
11210 }
11211
11212 3 int32_t d2=zc_oldrand()&1;
11213
11214
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(HeroDir()>=left)
11215 {
11216 d2+=2;
11217 }
11218
11219
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
3 if(canplace(d2) || canplace(d2^1))
11220 {
11221 3 misc=1;
11222 3 clk2=0;
11223 3 clk=0;
11224 3 }
11225 }
11226 3 break;
11227
11228 case 1:
11229
11230
3/8
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
51 if(++clk2>16||(!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk) && clk2>8)) misc=2;
11231
11232 51 break;
11233
11234 case 2:
11235
11236
3/8
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 21 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
24 if(++clk2>24||(!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk) && clk2>12)) misc=3;
11237
11238 24 break;
11239
11240 // case 3: if(stunclk) break; if(scored) dir^=1; if(!canmove(dir,false)) misc=4; else move((zfix)(d->step/100.0)); break;
11241 case 3:
11242
11243
3/6
✓ Branch 0 taken 186 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 186 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 186 times.
186 if(stunclk || frozenclock || watch) break;
11244
11245
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 186 times.
186 if(scored) dir^=1;
11246
11247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 186 times.
186 if(!canmove(dir,false)) misc=4;
11248 186 else move(zslongToFix(dstep*100));
11249
11250 186 break;
11251
11252 case 4:
11253 if (!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk)) misc = 2;
11254 if(--clk2<=16)
11255 {
11256 misc=5;
11257 clk=8;
11258 }
11259
11260 break;
11261
11262 case 5:
11263 if (!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk)) misc = 1;
11264 if(--clk2<=0) misc=((dmisc1==2)?-1:0);
11265
11266 break;
11267 } // switch(misc)
11268
11269 474 break;
11270
11271 default: //random
11272 // step=d->misc3/100.0;
11273
11274 step=zslongToFix(dmisc3*100);
11275 if (get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) || (!watch && !stunclk)) ++clk2;
11276 else if (!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk))
11277 {
11278 if (clk2 < 48) clk2+=2;
11279 if (clk2 >= 300) clk2-=2;
11280 }
11281
11282 if(clk2<32) misc=1;
11283 else if(clk2<48) misc=2;
11284 else if(clk2<300)
11285 {
11286 /*if(misc==2 && (int32_t)(dmisc3*0.48)%8)
11287 {
11288 fix_coords();
11289 }*/
11290 misc=3;
11291 step = zslongToFix(dstep*100);
11292 }
11293 else if(clk2<316) misc=2;
11294 else if(clk2<412) misc=1;
11295 else if(clk2<540)
11296 {
11297 misc=0;
11298 step=0;
11299 }
11300 else clk2=0;
11301
11302 if(clk2==48) clk=0;
11303
11304 // variable_walk(d->rate, d->homing, 0);
11305 variable_walk(rate, homing, 0);
11306 } // switch(dmisc1)
11307 474 }
11308
11309 703 hxofs=(misc>=2)?0:1000;
11310 703 return enemy::animate(index);
11311 721 }
11312
11313 4 bool eLeever::canplace(int32_t d2)
11314 {
11315 4 int32_t nx=HeroX();
11316 4 int32_t ny=HeroY();
11317
11318
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(d2<left) ny&=0xF0;
11319 else nx&=0xF0;
11320
11321
2/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 switch(d2)
11322 {
11323 // case up: ny-=((d->misc1==0)?32:48); break;
11324 // case down: ny+=((d->misc1==0)?32:48); if(ny-HeroY()<32) ny+=((d->misc1==0)?16:0); break;
11325 // case left: nx-=((d->misc1==0)?32:48); break;
11326 // case right: nx+=((d->misc1==0)?32:48); if(nx-HeroX()<32) nx+=((d->misc1==0)?16:0); break;
11327 case up:
11328
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 ny-=((dmisc1==0||dmisc1==2)?32:48);
11329 1 break;
11330
11331 case down:
11332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 ny+=((dmisc1==0||dmisc1==2)?32:48);
11333
11334
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 if(ny-HeroY()<32) ny+=((dmisc1==0||dmisc1==2)?16:0);
11335
11336 3 break;
11337
11338 case left:
11339 nx-=((dmisc1==0||dmisc1==2)?32:48);
11340 break;
11341
11342 case right:
11343 nx+=((dmisc1==0||dmisc1==2)?32:48);
11344
11345 if(nx-HeroX()<32) nx+=((dmisc1==0||dmisc1==2)?16:0);
11346
11347 break;
11348 }
11349
11350
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
4 if(m_walkflag(nx,ny,spw_halfstep, dir)||m_walkflag(nx,ny-8,spw_halfstep, dir)) /*none*/
11351 1 return false;
11352
11353
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(d2>=left)
11354 if(m_walkflag(HeroX(),HeroY(),spw_halfstep, dir)||m_walkflag(HeroX(),HeroY()-8,spw_halfstep, dir)) /*none*/
11355 return false;
11356
11357 3 x=nx;
11358 3 y=ny;
11359 3 dir=d2^1;
11360 3 return true;
11361 4 }
11362
11363 721 void eLeever::draw(BITMAP *dest)
11364 {
11365 // cs=d->cset;
11366 721 cs=dcset;
11367 721 update_enemy_frame();
11368
2/4
✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 721 times.
721 if(!fallclk&&!drownclk)
11369 {
11370
2/2
✓ Branch 0 taken 294 times.
✓ Branch 1 taken 427 times.
721 switch(misc)
11371 {
11372 case -1:
11373 case 0:
11374 427 return;
11375 }
11376 294 }
11377
11378 294 enemy::draw(dest);
11379 721 }
11380
11381 24 eWallM::eWallM(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
11382 24 {
11383 //zprint2("eWallM::eWallM\n");
11384 8 hashero=false;
11385 //nets+1000;
11386 8 SIZEflags = d->SIZEflags;
11387
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
8 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
11388 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
11389 // al_trace("Enemy txsz:%i\n", txsz);
11390
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
8 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
11391
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
11392
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
11393
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
11394
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
11395
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
11396 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
11397
1/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
11398
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
11399 {
11400 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
11401 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
11402 }
11403
11404
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
11405 16 }
11406
11407 4548 bool eWallM::animate(int32_t index)
11408 {
11409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4548 times.
4548 if(switch_hooked) return enemy::animate(index);
11410
2/4
✓ Branch 0 taken 4548 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4548 times.
4548 if(fallclk||drownclk)
11411 {
11412 return enemy::animate(index);
11413 }
11414
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 4530 times.
4548 if(dying)
11415 18 return Dead(index);
11416
11417
2/2
✓ Branch 0 taken 4253 times.
✓ Branch 1 taken 277 times.
4530 if(clk==0)
11418 {
11419 277 removearmos(x,y,ffcactivated);
11420 277 }
11421
11422 4530 hxofs=1000;
11423
2/2
✓ Branch 0 taken 902 times.
✓ Branch 1 taken 3628 times.
4530 if(misc==0) //inside wall, ready to spawn?
11424 {
11425 //zprint2("Wallmaster is ready to spawn, clk is: %d\n",clk);
11426 //zprint2("frame is: %d\n",frame);
11427 //zprint2("wallm_load_clk is: %d\n",wallm_load_clk);
11428
4/4
✓ Branch 0 taken 1303 times.
✓ Branch 1 taken 2325 times.
✓ Branch 2 taken 120 times.
✓ Branch 3 taken 1183 times.
3628 if(frame-wallm_load_clk>80 && clk>=0)
11429 {
11430 //zprint2("getting wall\n");
11431 1183 int32_t wall=hero_on_wall();
11432 //zprint2("Wallmaster wall is %d\n",wall);
11433 1183 int32_t wallm_cnt=0;
11434
11435
2/2
✓ Branch 0 taken 9464 times.
✓ Branch 1 taken 1183 times.
10647 for(int32_t i=0; i<guys.Count(); i++)
11436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9464 times.
18928 if(((enemy*)guys.spr(i))->family==eeWALLM)
11437 {
11438 9464 int32_t m=((enemy*)guys.spr(i))->misc;
11439
11440
4/4
✓ Branch 0 taken 1753 times.
✓ Branch 1 taken 7711 times.
✓ Branch 2 taken 1751 times.
✓ Branch 3 taken 2 times.
9464 if(m && ((enemy*)guys.spr(i))->clk3==(wall^1))
11441 {
11442 2 ++wallm_cnt;
11443 2 }
11444 9464 }
11445
11446
2/2
✓ Branch 0 taken 1178 times.
✓ Branch 1 taken 5 times.
1183 if(wall>0)
11447 {
11448 5 --wall;
11449 5 misc=1; //emerging from the wall?
11450 //zprint2("Wallmaster is emerging\n");
11451 5 clk2=0;
11452 5 clk3=wall^1;
11453 5 wallm_load_clk=frame;
11454
11455
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 if(wall<=down)
11456 {
11457
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if(HeroDir()==left)
11458 1 dir=right;
11459 else
11460 3 dir=left;
11461 4 }
11462 else
11463 {
11464
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(HeroDir()==up)
11465 1 dir=down;
11466 else
11467 dir=up;
11468 }
11469
11470
3/5
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
5 switch(wall)
11471 {
11472 case up:
11473 3 y=0;
11474 3 break;
11475
11476 case down:
11477 1 y=160;
11478 1 break;
11479
11480 case left:
11481 1 x=0;
11482 1 break;
11483
11484 case right:
11485 x=240;
11486 break;
11487 }
11488
11489 //zprint2("Wallmaster (p1) x is %d\n",x);
11490 //zprint2("Wallmaster (p1) y is %d\n",y);
11491
11492
3/5
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
5 switch(dir)
11493 {
11494 case up:
11495 y=(HeroY()+48-(wallm_cnt&1)*12);
11496 flip=wall&1;
11497 break;
11498
11499 case down:
11500 1 y=(HeroY()-48+(wallm_cnt&1)*12);
11501 1 flip=((wall&1)^1)+2;
11502 1 break;
11503
11504 case left:
11505 3 x=(HeroX()+48-(wallm_cnt&1)*12);
11506 3 flip=(wall==up?2:0)+1;
11507 3 break;
11508
11509 case right:
11510 1 x=(HeroX()-48+(wallm_cnt&1)*12);
11511 1 flip=(wall==up?2:0);
11512 1 break;
11513 }
11514
11515 //zprint2("Wallmaster (p2) x is %d\n",x);
11516 //zprint2("Wallmaster (p2) y is %d\n",y);
11517 5 }
11518 1183 }
11519 3628 }
11520 else
11521 902 wallm_crawl();
11522
11523 4530 return enemy::animate(index);
11524 4548 }
11525
11526 902 void eWallM::wallm_crawl()
11527 {
11528 902 bool w=watch;
11529 902 hxofs=0;
11530
11531
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 886 times.
902 if(slide())
11532 {
11533 16 return;
11534 }
11535
11536 // if(dying || watch || (!hashero && stunclk))
11537
4/8
✓ Branch 0 taken 886 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 886 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 886 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 886 times.
886 if(dying || (!hashero && ( stunclk || frozenclock )))
11538 {
11539 return;
11540 }
11541
11542 886 watch=false;
11543 886 ++clk2;
11544 // Misc1: slightly different movement
11545 //zprint2("wallmaster crawl\n");
11546 //zprint2("wallmaster tmpdstep is %d\n",tmpdstep);
11547 886 float tmpmisc3 = ((40.0/(int32_t)dstep)*40);
11548
11549 //int32_t tmpmisc = int32_t((40.0/dstep)*40);
11550 //zprint2("wallmaster crawl tmpmisc is: %d\n", tmpmisc);
11551 //zprint2("wallmaster crawl tmpmisc4 is: %d\n", tmpmisc4);
11552
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 886 times.
886 misc=(clk2/(dmisc1==1?40:(int32_t)tmpmisc3))+1;
11553 //zprint2("wallmaster crawl misc is: %d\n", misc);
11554
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 886 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
886 if(w&&misc>=3&&misc<=5)
11555 {
11556 --clk2;
11557 }
11558
11559
4/4
✓ Branch 0 taken 357 times.
✓ Branch 1 taken 367 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 2 times.
886 switch(misc)
11560 {
11561 case 1:
11562 case 2:
11563 367 zc_swap(dir,clk3);
11564 367 move(step);
11565 367 zc_swap(dir,clk3);
11566 367 break;
11567
11568 case 3:
11569 case 4:
11570 case 5:
11571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 357 times.
357 if(w)
11572 {
11573 watch=w;
11574 return;
11575 }
11576
11577 357 move(step);
11578 357 break;
11579
11580 case 6:
11581 case 7:
11582 160 zc_swap(dir,clk3);
11583 160 dir^=1;
11584 160 move(step);
11585 160 dir^=1;
11586 160 zc_swap(dir,clk3);
11587 160 break;
11588
11589 default:
11590 2 misc=0;
11591 2 break;
11592 }
11593
11594 886 watch=w;
11595 902 }
11596
11597 void eWallM::grabhero()
11598 {
11599 hashero=true;
11600 superman=1;
11601 }
11602
11603 4548 void eWallM::draw(BITMAP *dest)
11604 {
11605 4548 dummy_bool[1]=hashero;
11606 4548 update_enemy_frame();
11607
11608
4/6
✓ Branch 0 taken 3628 times.
✓ Branch 1 taken 920 times.
✓ Branch 2 taken 3628 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3628 times.
4548 if(misc>0 || fallclk||drownclk)
11609 {
11610 920 masked_draw(dest,16,playing_field_offset+16,224,144);
11611 920 }
11612
11613 // enemy::draw(dest);
11614 // tile = clk&8 ? 128:129;
11615 4548 }
11616
11617 bool eWallM::isSubmerged() const
11618 {
11619 return ( !misc );
11620 }
11621
11622 eTrap::eTrap(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
11623 {
11624 ox=x; //original x
11625 oy=y; //original y
11626 if(get_bit(quest_rules,qr_TRAPPOSFIX))
11627 {
11628 yofs = (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
11629 }
11630
11631 mainguy=false;
11632 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
11633 //nets+420;
11634 dummy_int[1]=0;
11635 SIZEflags = d->SIZEflags;
11636 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
11637 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
11638 // al_trace("Enemy txsz:%i\n", txsz);
11639 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
11640 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
11641 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
11642 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
11643 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
11644 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
11645 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
11646 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
11647 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
11648 {
11649 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
11650 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
11651 }
11652
11653 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
11654 }
11655
11656 bool eTrap::animate(int32_t index)
11657 {
11658 if(switch_hooked) return enemy::animate(index);
11659 if(fallclk||drownclk) return enemy::animate(index);
11660 if(clk<0)
11661 return enemy::animate(index);
11662
11663 if(clk==0)
11664 {
11665 removearmos(x,y,ffcactivated);
11666 }
11667
11668 if(misc==0) // waiting
11669 {
11670 ox = x;
11671 oy = y;
11672 double _MSVC2022_tmp1, _MSVC2022_tmp2;
11673 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
11674
11675 if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
11676 {
11677 dir=down;
11678 }
11679 else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
11680 {
11681 dir=right;
11682 }
11683 else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/4)))
11684 {
11685 dir=up;
11686 }
11687 else
11688 {
11689 dir=left;
11690 }
11691
11692 int32_t d2=lined_up(15,true);
11693
11694 if(((d2<left || d2 > right) && (dmisc1==1)) ||
11695 ((d2>down) && (dmisc1==2)) ||
11696 ((d2>right) && (!dmisc1)) ||
11697 ((d2<l_up) && (dmisc1==4)) ||
11698 ((d2!=r_up) && (d2!=l_down) && (dmisc1==6)) ||
11699 ((d2!=l_up) && (d2!=r_down) && (dmisc1==8)))
11700 {
11701 d2=-1;
11702 }
11703
11704 if(d2!=-1 && trapmove(d2))
11705 {
11706 dir=d2;
11707 misc=1;
11708 clk2=(dir==down)?3:0;
11709 }
11710 }
11711
11712 if(misc==1) // charging
11713 {
11714 clk2=(clk2+1)&3;
11715 step=(clk2==3)?1:2;
11716
11717 if(!trapmove(dir) || clip())
11718 {
11719 misc=2;
11720
11721 if(dir<l_up)
11722 {
11723 dir=dir^1;
11724 }
11725 else
11726 {
11727 dir=dir^3;
11728 }
11729 }
11730 else
11731 {
11732 sprite::move(step);
11733 }
11734 }
11735
11736 if(misc==2) // retreating
11737 {
11738 step=(++clk2&1)?1:0;
11739
11740 switch(dir)
11741 {
11742 case up:
11743 if(int32_t(y)<=oy) goto trap_rest;
11744 else sprite::move(step);
11745
11746 break;
11747
11748 case left:
11749 if(int32_t(x)<=ox) goto trap_rest;
11750 else sprite::move(step);
11751
11752 break;
11753
11754 case down:
11755 if(int32_t(y)>=oy) goto trap_rest;
11756 else sprite::move(step);
11757
11758 break;
11759
11760 case right:
11761 if(int32_t(x)>=ox) goto trap_rest;
11762 else sprite::move(step);
11763
11764 break;
11765
11766 case l_up:
11767 if(int32_t(x)<=ox && int32_t(y)<=oy) goto trap_rest;
11768 else sprite::move(step);
11769
11770 break;
11771
11772 case r_up:
11773 if(int32_t(x)>=ox && int32_t(y)<=oy) goto trap_rest;
11774 else sprite::move(step);
11775
11776 break;
11777
11778 case l_down:
11779 if(int32_t(x)<=ox && int32_t(y)>=oy) goto trap_rest;
11780 else sprite::move(step);
11781
11782 break;
11783
11784 case r_down:
11785 if(int32_t(x)>=ox && int32_t(y)>=oy) goto trap_rest;
11786 else sprite::move(step);
11787
11788 break;
11789 trap_rest:
11790 {
11791 x=ox;
11792 y=oy;
11793 misc=0;
11794 }
11795 }
11796 }
11797
11798 return enemy::animate(index);
11799 }
11800
11801 bool eTrap::trapmove(int32_t ndir)
11802 {
11803 if(get_bit(quest_rules,qr_MEANTRAPS))
11804 {
11805 if(tmpscr->flags2&fFLOATTRAPS)
11806 return canmove(ndir,(zfix)1,spw_floater, 0, 0, 15, 15,false);
11807
11808 return canmove(ndir,(zfix)1,spw_water, 0, 0, 15, 15,false);
11809 }
11810
11811 if(oy==80 && !(ndir==left || ndir == right))
11812 return false;
11813
11814 if(ox==128 && !(ndir==up || ndir==down))
11815 return false;
11816
11817 if(oy<80 && ndir==up)
11818 return false;
11819
11820 if(oy>80 && ndir==down)
11821 return false;
11822
11823 if(ox<128 && ndir==left)
11824 return false;
11825
11826 if(ox>128 && ndir==right)
11827 return false;
11828
11829 if(ox<128 && oy<80 && ndir==l_up)
11830 return false;
11831
11832 if(ox<128 && oy>80 && ndir==l_down)
11833 return false;
11834
11835 if(ox>128 && oy<80 && ndir==r_up)
11836 return false;
11837
11838 if(ox>128 && oy>80 && ndir==r_down)
11839 return false;
11840
11841 return true;
11842 }
11843
11844 bool eTrap::clip()
11845 {
11846 if(get_bit(quest_rules,qr_MEANPLACEDTRAPS))
11847 {
11848 switch(dir)
11849 {
11850 case up:
11851 if(y<=0) return true;
11852
11853 break;
11854
11855 case down:
11856 if(y>=160) return true;
11857
11858 break;
11859
11860 case left:
11861 if(x<=0) return true;
11862
11863 break;
11864
11865 case right:
11866 if(x>=240) return true;
11867
11868 break;
11869
11870 case l_up:
11871 if(y<=0||x<=0) return true;
11872
11873 break;
11874
11875 case l_down:
11876 if(y>=160||x<=0) return true;
11877
11878 break;
11879
11880 case r_up:
11881 if(y<=0||x>=240) return true;
11882
11883 break;
11884
11885 case r_down:
11886 if(y>=160||x>=240) return true;
11887
11888 break;
11889 }
11890
11891 return false;
11892 }
11893 else
11894 {
11895 switch(dir)
11896 {
11897 case up:
11898 if(oy>80 && y<=86) return true;
11899
11900 break;
11901
11902 case down:
11903 if(oy<80 && y>=80) return true;
11904
11905 break;
11906
11907 case left:
11908 if(ox>128 && x<=124) return true;
11909
11910 break;
11911
11912 case right:
11913 if(ox<120 && x>=116) return true;
11914
11915 break;
11916
11917 case l_up:
11918 if(oy>80 && y<=86 && ox>128 && x<=124) return true;
11919
11920 break;
11921
11922 case l_down:
11923 if(oy<80 && y>=80 && ox>128 && x<=124) return true;
11924
11925 break;
11926
11927 case r_up:
11928 if(oy>80 && y<=86 && ox<120 && x>=116) return true;
11929
11930 break;
11931
11932 case r_down:
11933 if(oy<80 && y>=80 && ox<120 && x>=116) return true;
11934
11935 break;
11936 }
11937
11938 return false;
11939 }
11940 }
11941
11942 void eTrap::draw(BITMAP *dest)
11943 {
11944 update_enemy_frame();
11945 enemy::draw(dest);
11946 }
11947
11948 int32_t eTrap::takehit(weapon*)
11949 {
11950 return 0;
11951 }
11952
11953 eTrap2::eTrap2(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
11954 {
11955 lasthit=-1;
11956 lasthitclk=0;
11957 mainguy=false;
11958 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
11959 step=2;
11960 if(dmisc1==1 || (dmisc1==0 && zc_oldrand()&2))
11961 {
11962 dir=(x<=112)?right:left;
11963 }
11964 else
11965 {
11966 dir=(y<=72)?down:up;
11967 }
11968
11969 if(get_bit(quest_rules,qr_TRAPPOSFIX))
11970 {
11971 yofs = (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
11972 }
11973
11974 //nets+((id==eTRAP_LR)?540:520);
11975 dummy_int[1]=0;
11976 SIZEflags = d->SIZEflags;
11977 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
11978 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
11979 // al_trace("Enemy txsz:%i\n", txsz);
11980 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
11981 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
11982 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
11983 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
11984 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
11985 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
11986 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
11987 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
11988 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
11989 {
11990 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
11991 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
11992 }
11993
11994 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
11995 }
11996
11997 bool eTrap2::animate(int32_t index)
11998 {
11999 if(switch_hooked) return enemy::animate(index);
12000 if(fallclk||drownclk) return enemy::animate(index);
12001 if(clk<0)
12002 return enemy::animate(index);
12003
12004 if(clk==0)
12005 {
12006 removearmos(x,y,ffcactivated);
12007 }
12008
12009 if(!get_bit(quest_rules,qr_PHANTOMPLACEDTRAPS))
12010 {
12011 if(lasthitclk>0)
12012 {
12013 --lasthitclk;
12014 }
12015 else
12016 {
12017 lasthit=-1;
12018 }
12019
12020 bool hitenemy=false;
12021
12022 for(int32_t j=0; j<guys.Count(); j++)
12023 {
12024 if((j!=index) && (lasthit!=j))
12025 {
12026 if(hit(guys.spr(j)))
12027 {
12028 lasthit=j;
12029 lasthitclk=10;
12030 hitenemy=true;
12031 guys.spr(j)->lasthit=index;
12032 guys.spr(j)->lasthitclk=10;
12033 // guys.spr(j)->dir=guys.spr(j)->dir^1;
12034 }
12035 }
12036 }
12037
12038 if(!trapmove(dir) || clip() || hitenemy)
12039 {
12040 if(!trapmove(dir) || clip())
12041 {
12042 lasthit=-1;
12043 lasthitclk=0;
12044 }
12045
12046 if(get_bit(quest_rules,qr_MORESOUNDS))
12047 sfx(WAV_ZN1TAP,pan(int32_t(x)));
12048
12049 dir=dir^1;
12050 }
12051
12052 sprite::move(step);
12053 }
12054 else
12055 {
12056 if(!trapmove(dir) || clip())
12057 {
12058 if(get_bit(quest_rules,qr_MORESOUNDS))
12059 sfx(WAV_ZN1TAP,pan(int32_t(x)));
12060
12061 dir=dir^1;
12062 }
12063
12064 sprite::move(step);
12065 }
12066
12067 return enemy::animate(index);
12068 }
12069
12070 bool eTrap2::trapmove(int32_t ndir)
12071 {
12072 if(tmpscr->flags2&fFLOATTRAPS)
12073 return canmove(ndir,(zfix)1,spw_floater, 0, 0, 15, 15,false);
12074
12075 return canmove(ndir,(zfix)1,spw_water, 0, 0, 15, 15,false);
12076 }
12077
12078 bool eTrap2::clip()
12079 {
12080 switch(dir)
12081 {
12082 case up:
12083 if(y<=0) return true;
12084
12085 break;
12086
12087 case down:
12088 if(y>=160) return true;
12089
12090 break;
12091
12092 case left:
12093 if(x<=0) return true;
12094
12095 break;
12096
12097 case right:
12098 if(x>=240) return true;
12099
12100 break;
12101 }
12102
12103 return false;
12104 }
12105
12106 void eTrap2::draw(BITMAP *dest)
12107 {
12108 update_enemy_frame();
12109 enemy::draw(dest);
12110 }
12111
12112 int32_t eTrap2::takehit(weapon*)
12113 {
12114 return 0;
12115 }
12116
12117 eRock::eRock(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12118 {
12119 //do not show "enemy appering" anim -DD
12120 clk=0;
12121 mainguy=false;
12122 clk2=-14;
12123 //Enemy Editor Size Tab
12124 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12125 else hxofs = -2;
12126 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12127 else hyofs = -2;
12128 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
12129 else hxsz = 20;
12130 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && d->hysz >= 0 ) hysz = d->hysz;
12131 else hysz=20;
12132
12133 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && d->txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12134 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && d->tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12135 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && d->hzsz >= 0 ) hzsz = d->hzsz;
12136 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
12137 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12138 {
12139 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12140 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12141 }
12142
12143 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
12144 //nets+1640;
12145 }
12146
12147 bool eRock::animate(int32_t index)
12148 {
12149 if(switch_hooked) return enemy::animate(index);
12150 if(fallclk||drownclk) return enemy::animate(index);
12151 if(dying)
12152 return Dead(index);
12153
12154 if(clk==0)
12155 {
12156 removearmos(x,y,ffcactivated);
12157 }
12158
12159 if(++clk2==0) // start it
12160 {
12161 x=zc_oldrand()&0xF0;
12162 y=0;
12163 clk3=0;
12164 clk2=zc_oldrand()&15;
12165 }
12166
12167 if(clk2>16) // move it
12168 {
12169 if(clk3<=0) // start bounce
12170 {
12171 dir=zc_oldrand()&1;
12172
12173 if(x<32) dir=1;
12174
12175 if(x>208) dir=0;
12176 }
12177
12178 if(clk3<13+16)
12179 {
12180 x += dir ? 1 : -1; //right, left
12181 dummy_int[1]=dir;
12182
12183 if(clk3<2)
12184 {
12185 y-=2; //up
12186 dummy_int[2]=(dummy_int[1]==1)?r_up:l_up;
12187 }
12188 else if(clk3<5)
12189 {
12190 y--; //up
12191 dummy_int[2]=(dummy_int[1]==1)?r_up:l_up;
12192 }
12193 else if(clk3<8)
12194 {
12195 dummy_int[2]=(dummy_int[1]==1)?right:left;
12196 }
12197 else if(clk3<11)
12198 {
12199 y++; //down
12200 dummy_int[2]=(dummy_int[1]==1)?r_down:l_down;
12201 }
12202 else
12203 {
12204 y+=2; //down
12205 dummy_int[2]=(dummy_int[1]==1)?r_down:l_down;
12206 }
12207
12208 ++clk3;
12209 }
12210 else if(y<176)
12211 clk3=0; // next bounce
12212 else
12213 clk2 = -(zc_oldrand()&63); // back to top
12214 }
12215
12216 return enemy::animate(index);
12217 }
12218
12219 void eRock::drawshadow(BITMAP *dest, bool translucent)
12220 {
12221 if(clk2>=0)
12222 {
12223 int32_t tempy=yofs;
12224 flip = 0;
12225 int32_t fdiv = frate/4;
12226 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
12227 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
12228 efrate:((clk>=(frate>>1))?1:0);
12229 shadowtile = wpnsbuf[spr_shadow].tile+f2;
12230
12231 yofs+=8;
12232 yofs+=zc_max(0,zc_min(29-clk3,clk3));
12233 if(!shadow_overpit(this))
12234 enemy::drawshadow(dest, translucent);
12235 yofs=tempy;
12236 }
12237 }
12238
12239 void eRock::draw(BITMAP *dest)
12240 {
12241 if(clk2>=0 || fallclk||drownclk)
12242 {
12243 int32_t tempdir=dir;
12244 dir=dummy_int[2];
12245 update_enemy_frame();
12246 enemy::draw(dest);
12247 dir=tempdir;
12248 }
12249 }
12250
12251 int32_t eRock::takehit(weapon*)
12252 {
12253 return 0;
12254 }
12255
12256 eBoulder::eBoulder(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12257 {
12258 clk=0;
12259 mainguy=false;
12260 clk2=-14;
12261 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12262 else hxofs= -10;
12263 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12264 else hyofs=-10;
12265 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
12266 else hxsz=36;
12267 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && d->hysz >= 0 ) hysz = d->hysz;
12268 else hysz=36;
12269 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && d->hzsz >= 0 ) hzsz = d->hzsz;
12270 else hzsz=16; //can't be jumped
12271
12272 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && d->txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12273 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && d->tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12274 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
12275 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
12276 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12277 {
12278 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12279 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12280 }
12281
12282 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
12283 //nets+1680;
12284 }
12285
12286 bool eBoulder::animate(int32_t index)
12287 {
12288 if(switch_hooked) return enemy::animate(index);
12289 if(fallclk||drownclk) return enemy::animate(index);
12290 if(dying)
12291 return Dead(index);
12292
12293 if(clk==0)
12294 {
12295 removearmos(x,y,ffcactivated);
12296 }
12297
12298 zfix *vert;
12299 vert = (moveflags & FLAG_USE_FAKE_Z) ? &fakez : get_bit(quest_rules,qr_ENEMIESZAXIS) ? &z : &y;
12300
12301 if(++clk2==0) // start it
12302 {
12303 x=zc_oldrand()&0xF0;
12304 y=-32;
12305 clk3=0;
12306 clk2=zc_oldrand()&15;
12307 }
12308
12309 if(clk2>16) // move it
12310 {
12311 if(clk3<=0) // start bounce
12312 {
12313 dir=zc_oldrand()&1;
12314
12315 if(x<32) dir=1;
12316
12317 if(x>208) dir=0;
12318 }
12319
12320 if(clk3<13+16)
12321 {
12322 x += dir ? 1 : -1; //right, left
12323 dummy_int[1]=dir;
12324
12325 if(clk3<2)
12326 {
12327 y-=2; //up
12328 dummy_int[2]=(dummy_int[1]==1)?r_up:l_up;
12329 }
12330 else if(clk3<5)
12331 {
12332 y--; //up
12333 dummy_int[2]=(dummy_int[1]==1)?r_up:l_up;
12334 }
12335 else if(clk3<8)
12336 {
12337 dummy_int[2]=(dummy_int[1]==1)?right:left;
12338 }
12339 else if(clk3<11)
12340 {
12341 y++; //down
12342 dummy_int[2]=(dummy_int[1]==1)?r_down:l_down;
12343 }
12344 else
12345 {
12346 y+=2; //down
12347 dummy_int[2]=(dummy_int[1]==1)?r_down:l_down;
12348 }
12349
12350 ++clk3;
12351 }
12352 else if(y<176)
12353 clk3=0; // next bounce
12354 else
12355 clk2 = -(zc_oldrand()&63); // back to top
12356 }
12357
12358 return enemy::animate(index);
12359 }
12360
12361 void eBoulder::drawshadow(BITMAP *dest, bool translucent)
12362 {
12363 if(clk2>=0)
12364 {
12365 int32_t tempy=yofs;
12366 flip = 0;
12367 int32_t f2=((clk<<2)/frate)<<1;
12368 shadowtile = wpnsbuf[spr_shadow].tile+f2;
12369 yofs+=zc_max(0,zc_min(29-clk3,clk3));
12370
12371 yofs+=8;
12372 xofs-=8;
12373 if(!shadow_overpit(this))
12374 enemy::drawshadow(dest, translucent);
12375 xofs+=16;
12376 ++shadowtile;
12377 if(!shadow_overpit(this))
12378 enemy::drawshadow(dest, translucent);
12379 yofs+=16;
12380 shadowtile+=20;
12381 if(!shadow_overpit(this))
12382 enemy::drawshadow(dest, translucent);
12383 xofs-=16;
12384 --shadowtile;
12385 if(!shadow_overpit(this))
12386 enemy::drawshadow(dest, translucent);
12387 xofs+=8;
12388 yofs=tempy;
12389 }
12390 }
12391
12392 void eBoulder::draw(BITMAP *dest)
12393 {
12394 if(clk2>=0 || fallclk||drownclk)
12395 {
12396 int32_t tempdir=dir;
12397 dir=dummy_int[2];
12398 update_enemy_frame();
12399 dir=tempdir;
12400 xofs-=8;
12401 yofs-=8;
12402 drawblock(dest,15);
12403 xofs+=8;
12404 yofs+=8;
12405 // enemy::draw(dest);
12406 }
12407 }
12408
12409 int32_t eBoulder::takehit(weapon*)
12410 {
12411 return 0;
12412 }
12413
12414 6 eProjectile::eProjectile(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk),
12415
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 minRange(get_bit(quest_rules, qr_BROKENSTATUES) ? 0 : Clk)
12416 6 {
12417 /* fixing
12418 hp=1;
12419 */
12420 2 mainguy=false;
12421
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
12422 2 hclk=clk; // the "no fire" range
12423 2 clk=0;
12424 2 clk3=96;
12425 2 timer=0;
12426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(o_tile==0)
12427 {
12428 2 superman=1;
12429 2 hxofs=1000;
12430 2 }
12431 2 SIZEflags = d->SIZEflags;
12432
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12433 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
12434 // al_trace("Enemy txsz:%i\n", txsz);
12435
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12436
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
12437
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
12438
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
12439
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12440
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12441 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
12442
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
12443
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12444 {
12445 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12446 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12447 }
12448
12449
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
12450 4 }
12451
12452 80 bool eProjectile::animate(int32_t index)
12453 {
12454
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
80 if(switch_hooked) return enemy::animate(index);
12455
2/4
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 80 times.
80 if(fallclk||drownclk) return enemy::animate(index);
12456
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if(clk==0)
12457 {
12458 2 removearmos(x,y,ffcactivated);
12459 2 }
12460
12461 double _MSVC2022_tmp1, _MSVC2022_tmp2;
12462 80 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
12463
12464
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
80 if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
12465 {
12466 dir=down;
12467 }
12468
2/4
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 80 times.
80 else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
12469 {
12470 80 dir=right;
12471 80 }
12472 else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/4)))
12473 {
12474 dir=up;
12475 }
12476 else
12477 {
12478 dir=left;
12479 }
12480
12481
3/4
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 57 times.
80 if(!stunclk && ++clk3>80)
12482 {
12483
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(dmisc1==9) // Breath type
12484 {
12485 if(timer==0)
12486 {
12487 unsigned r=zc_oldrand();
12488
12489 if(!(r&63))
12490 {
12491 timer=zc_oldrand()%50+50;
12492 }
12493 }
12494
12495 if(timer>0)
12496 {
12497 if(timer%4==0)
12498 {
12499 FireBreath(false);
12500 }
12501
12502 if(--timer==0)
12503 {
12504 clk3=0;
12505 }
12506 }
12507 }
12508
12509 else // Not breath type
12510 {
12511 57 unsigned r=zc_oldrand();
12512
12513
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
57 if(!(r&63) && !HeroInRange(minRange))
12514 {
12515 1 FireWeapon();
12516
12517
1/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if(get_bit(quest_rules, qr_BROKENSTATUES)==0 &&
12518
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 ((wpn==ewFireball || wpn==ewFireball2) || dmisc1==e1tNORMAL))
12519 {
12520
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(!((r>>7)&15))
12521 {
12522 x-=4;
12523 FireWeapon();
12524 x+=4;
12525 }
12526 1 }
12527
12528 1 clk3=0;
12529 1 }
12530 }
12531 57 }
12532
12533 80 return enemy::animate(index);
12534 80 }
12535
12536 78 void eProjectile::draw(BITMAP *dest)
12537 {
12538 78 update_enemy_frame();
12539 78 enemy::draw(dest);
12540 78 }
12541
12542 eTrigger::eTrigger(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12543 {
12544 hxofs=1000;
12545 }
12546
12547 void eTrigger::draw(BITMAP *dest)
12548 {
12549 update_enemy_frame();
12550 enemy::draw(dest);
12551 }
12552
12553 void eTrigger::death_sfx()
12554 {
12555 //silent death
12556 }
12557
12558 eNPC::eNPC(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12559 {
12560 o_tile+=wpnsbuf[iwNPCs].tile;
12561 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
12562 SIZEflags = d->SIZEflags;
12563 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12564 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
12565 // al_trace("Enemy txsz:%i\n", txsz);
12566 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12567 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
12568 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
12569 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
12570 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12571 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12572 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
12573 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
12574 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12575 {
12576 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12577 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12578 }
12579
12580 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
12581 }
12582
12583 bool eNPC::animate(int32_t index)
12584 {
12585 if(switch_hooked) return enemy::animate(index);
12586 if(dying)
12587 return Dead(index);
12588
12589 if(clk==0)
12590 {
12591 removearmos(x,y,ffcactivated);
12592 }
12593
12594 switch(dmisc2)
12595 {
12596 case 0:
12597 {
12598 double _MSVC2022_tmp1, _MSVC2022_tmp2;
12599 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
12600
12601 if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
12602 {
12603 dir=down;
12604 }
12605
12606 else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
12607 {
12608 dir=right;
12609 }
12610 else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/8)))
12611 {
12612 dir=up;
12613 }
12614 else
12615 {
12616 dir=left;
12617 }
12618 }
12619 break;
12620
12621 case 1:
12622 halting_walk(rate, homing, 0, hrate, 48);
12623
12624 if(clk2==1 && (misc < dmisc1) && !(zc_oldrand()&15))
12625 {
12626 newdir(rate, homing, 0);
12627 clk2=48;
12628 ++misc;
12629 }
12630
12631 if(clk2==0)
12632 misc=0;
12633
12634 break;
12635 }
12636
12637 return enemy::animate(index);
12638 }
12639
12640 void eNPC::draw(BITMAP *dest)
12641 {
12642 update_enemy_frame();
12643 enemy::draw(dest);
12644 }
12645
12646 int32_t eNPC::takehit(weapon*)
12647 {
12648 return 0;
12649 }
12650
12651 eSpinTile::eSpinTile(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12652 {
12653 if(clk>0) // clk>0 when created by a Spinning Tile combo
12654 {
12655 o_tile=clk;
12656 cs=id>>12;
12657 }
12658
12659 id=id&0xFFF;
12660 clk=0;
12661 step=0;
12662 mainguy=false;
12663 SIZEflags = d->SIZEflags;
12664 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12665 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
12666 // al_trace("Enemy txsz:%i\n", txsz);
12667 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12668 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
12669 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
12670 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
12671 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12672 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12673 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
12674 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
12675 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12676 {
12677 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12678 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12679 }
12680
12681 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
12682 }
12683
12684 void eSpinTile::facehero()
12685 {
12686 if(Hero.x-x==0)
12687 {
12688 if (Hero.y + 8 < y)
12689 dir = up;
12690 else
12691 dir = down;
12692 }
12693 else
12694 {
12695 double _MSVC2022_tmp1, _MSVC2022_tmp2;
12696 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
12697
12698 if((ddir <= -5.0*PI/8.0) && (ddir > -7.0*PI/8.0))
12699 {
12700 dir=l_down;
12701 }
12702 else if ((ddir <= -3.0*PI / 8.0) && (ddir > -5.0*PI / 8.0))
12703 {
12704 dir=down;
12705 }
12706 else if ((ddir <= -1.0*PI / 8.0) && (ddir > -3.0*PI / 8.0))
12707 {
12708 dir=r_down;
12709 }
12710 else if ((ddir <= 1.0*PI / 8.0) && (ddir > -1.0*PI / 8.0))
12711 {
12712 dir=right;
12713 }
12714 else if ((ddir <= 3.0*PI / 8.0) && (ddir > 1.0*PI / 8.0))
12715 {
12716 dir=r_up;
12717 }
12718 else if ((ddir <= 5.0*PI / 8.0) && (ddir > 3.0*PI / 8.0))
12719 {
12720 dir=up;
12721 }
12722 else if ((ddir <= 7.0*PI / 8.0) && (ddir > 5.0*PI / 8.0))
12723 {
12724 dir=l_up;
12725 }
12726 else
12727 {
12728 dir=left;
12729 }
12730 }
12731 }
12732
12733
12734 bool eSpinTile::animate(int32_t index)
12735 {
12736 if(switch_hooked) return enemy::animate(index);
12737 if(fallclk||drownclk) return enemy::animate(index);
12738 if(dying)
12739 {
12740 return Dead(index);
12741 }
12742
12743 if(clk==0)
12744 {
12745 removearmos(x,y,ffcactivated);
12746 }
12747
12748 ++misc;
12749
12750 if(misc==96)
12751 {
12752 facehero();
12753 double _MSVC2022_tmp1, _MSVC2022_tmp2;
12754 double ddir=atan2_MSVC2022_FIX(double((Hero.y)-y),double(Hero.x-x));
12755 angular=true;
12756 angle=ddir;
12757 step=zslongToFix(dstep*100);
12758 }
12759
12760 if(y>186 || y<=-16 || x>272 || x<=-16)
12761 kickbucket();
12762
12763 sprite::move(step);
12764 return enemy::animate(index);
12765 }
12766
12767 void eSpinTile::draw(BITMAP *dest)
12768 {
12769 update_enemy_frame();
12770 y-=(misc>>4);
12771 yofs+=2;
12772 enemy::draw(dest);
12773 yofs-=2;
12774 y+=(misc>>4);
12775 }
12776
12777 void eSpinTile::drawshadow(BITMAP *dest, bool translucent)
12778 {
12779 flip = 0;
12780 shadowtile = wpnsbuf[spr_shadow].tile+(clk%4);
12781 yofs+=4;
12782 if(!shadow_overpit(this))
12783 enemy::drawshadow(dest, translucent);
12784 yofs-=4;
12785 }
12786
12787 6 eZora::eZora(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,0)
12788 6 {
12789 //these are here to bypass compiler warnings about unused arguments
12790 2 Clk=Clk;
12791 2 mainguy=false;
12792
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
12793 /*if((x>-17 && x<0) && iswaterex(tmpscr->data[(((int32_t)y&0xF0)+((int32_t)x>>4))]))
12794 {
12795 clk=1;
12796 }*/
12797 //nets+880;
12798 2 SIZEflags = d->SIZEflags;
12799
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12800 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
12801 // al_trace("Enemy txsz:%i\n", txsz);
12802
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12803
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
12804
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
12805
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
12806
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12807
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12808 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
12809
1/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
12810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12811 {
12812 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12813 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12814 }
12815
12816
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
12817 4 }
12818
12819 void eZora::facehero()
12820 {
12821 if(Hero.x-x==0)
12822 {
12823 dir=(Hero.y+8<y)?up:down;
12824 }
12825 else
12826 {
12827 double _MSVC2022_tmp1, _MSVC2022_tmp2;
12828 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
12829
12830 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
12831 {
12832 dir=l_down;
12833 }
12834 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
12835 {
12836 dir=down;
12837 }
12838 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
12839 {
12840 dir=r_down;
12841 }
12842 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
12843 {
12844 dir=right;
12845 }
12846 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
12847 {
12848 dir=r_up;
12849 }
12850 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
12851 {
12852 dir=up;
12853 }
12854 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
12855 {
12856 dir=l_up;
12857 }
12858 else
12859 {
12860 dir=left;
12861 }
12862 }
12863 }
12864
12865 514 bool eZora::animate(int32_t index)
12866 {
12867
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 514 times.
514 if(switch_hooked) return enemy::animate(index);
12868
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 514 times.
514 if(dying)
12869 return Dead(index);
12870
12871
2/2
✓ Branch 0 taken 511 times.
✓ Branch 1 taken 3 times.
514 if(clk==0)
12872 {
12873 3 removearmos(x,y,ffcactivated);
12874 3 }
12875
12876
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 514 times.
514 if(watch)
12877 {
12878 ++clock_zoras[id];
12879 return true;
12880 }
12881
12882
1/2
✓ Branch 0 taken 514 times.
✗ Branch 1 not taken.
514 if(get_bit(quest_rules,qr_NEWENEMYTILES))
12883 {
12884 facehero();
12885 }
12886
12887
6/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 501 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1 times.
514 switch(clk)
12888 {
12889 case 0: // reposition him
12890 {
12891 3 int32_t t=0;
12892 3 int32_t pos2=zc_oldrand()%160 + 16;
12893 3 bool placed=false;
12894
12895
4/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3 times.
9 while(!placed && t<160)
12896 {
12897 6 int32_t watertype = iswaterex(tmpscr->data[pos2], currmap, currscr, -1, ((pos2)%16*16), ((pos2)&0xF0), false, true, true, (bool)(editorflags & ENEMY_FLAG7));
12898
4/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
9 if(watertype && ((editorflags & ENEMY_FLAG6) ||
12899
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 ((combobuf[watertype].usrflags&cflag1) && (editorflags & ENEMY_FLAG5))
12900
3/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
3 || (!(combobuf[watertype].usrflags&cflag1) && !(editorflags & ENEMY_FLAG5))) && (pos2&15)>0 && (pos2&15)<15)
12901 {
12902 3 x=(pos2&15)<<4;
12903 3 y=pos2&0xF0;
12904
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(editorflags & ENEMY_FLAG8)) hp=guysbuf[id&0xFFF].hp; // refill life each time, unless the flag is checked.
12905 3 hxofs=1000; // avoid hit detection
12906 3 stunclk=0;
12907 3 placed=true;
12908 3 }
12909
12910 12 pos2+=19;
12911
12912
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
12 if(pos2>=176)
12913 1 pos2-=160;
12914
12915 6 ++t;
12916 }
12917
12918
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if(!placed || whistleclk>=88) // can't place him, he's gone
12919 return true;
12920
12921 }
12922 3 break;
12923
12924 case 35:
12925
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(!get_bit(quest_rules,qr_NEWENEMYTILES))
12926 {
12927 3 dir=(Hero.y+8<y)?up:down;
12928 3 }
12929
12930 3 hxofs=0;
12931 3 break;
12932
12933 case 35+19:
12934 3 addEwpn(x,y,z,wpn,2,wdp,dir,getUID(), 0, fakez);
12935 3 sfx(wpnsfx(wpn),pan(int32_t(x)));
12936 3 break;
12937
12938 case 35+66:
12939 3 hxofs=1000;
12940 3 break;
12941
12942 case 198:
12943 1 clk=-1;
12944 1 break;
12945 }
12946
12947 514 return enemy::animate(index);
12948 514 }
12949
12950 514 void eZora::draw(BITMAP *dest)
12951 {
12952
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 505 times.
514 if(clk<3)
12953 9 return;
12954
12955 505 update_enemy_frame();
12956 505 enemy::draw(dest);
12957 514 }
12958
12959 bool eZora::isSubmerged() const
12960 {
12961 return ( clk < 3 );
12962 }
12963
12964
4/8
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 94 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 94 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 94 times.
✗ Branch 7 not taken.
376 eStalfos::eStalfos(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12965 282 {
12966 94 multishot= timer = fired = dashing = 0;
12967 94 hashero = false;
12968 94 dummy_bool[0]=false;
12969 94 shield= (flags&(inv_left | inv_right | inv_back |inv_front)) != 0;
12970
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
94 if(dmisc9==e9tARMOS && zc_oldrand()&1)
12971 {
12972 step=zslongToFix(dmisc10*100);
12973
12974 if(anim==aARMOS4) o_tile+=20;
12975 }
12976
12977
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
94 if(flags & guy_fadeflicker)
12978 {
12979 clk=0;
12980 superman = 1;
12981 fading=fade_flicker;
12982 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
12983 dir=down;
12984
12985 if(!canmove(down,(zfix)8,spw_none,false))
12986 clk3=int32_t(13.0/step);
12987 }
12988
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 else if(flags & guy_fadeinstant)
12989 {
12990 clk=0;
12991 }
12992
12993
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 shadowdistance = 0;
12994 94 clk4 = clk5 = 0;
12995 //nets+2380;
12996 94 SIZEflags = d->SIZEflags;
12997
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
94 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12998 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
12999 // al_trace("Enemy txsz:%i\n", txsz);
13000
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
94 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
13001
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
94 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
13002
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
94 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
13003
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
94 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
13004
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
13005
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
13006 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
13007
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
94 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
13008
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
94 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
13009 {
13010 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
13011 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
13012 }
13013
13014
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
94 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
13015 188 }
13016
13017 37149 bool eStalfos::animate(int32_t index)
13018 {
13019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37149 times.
37149 if(switch_hooked) return enemy::animate(index);
13020
2/4
✓ Branch 0 taken 37149 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 37149 times.
37149 if(fallclk||drownclk)
13021 {
13022 return enemy::animate(index);
13023 }
13024
2/2
✓ Branch 0 taken 684 times.
✓ Branch 1 taken 36465 times.
37149 if(dying)
13025 {
13026
1/2
✓ Branch 0 taken 684 times.
✗ Branch 1 not taken.
684 if(hashero)
13027 {
13028 Hero.setEaten(0);
13029 hashero=false;
13030 }
13031
13032
1/14
✗ Branch 0 not taken.
✓ Branch 1 taken 684 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
684 if(dmisc9==e9tROPE && dmisc2==e2tBOMBCHU && !fired && (hp<=0 && !immortal) && hp>-1000 && wpn>wEnemyWeapons)
13033 {
13034 hp=-1000;
13035 weapon *ew=new weapon(x,y,z, wpn, 0, dmisc4, dir,-1,getUID(),false);
13036 Ewpns.add(ew);
13037 ew->fakez = fakez;
13038
13039 if(wpn==ewSBomb || wpn==ewBomb)
13040 {
13041 ew->step=0;
13042 ew->id=wpn;
13043 ew->misc=50;
13044 ew->clk=48;
13045 }
13046
13047 fired=true;
13048 }
13049
5/6
✓ Branch 0 taken 306 times.
✓ Branch 1 taken 378 times.
✓ Branch 2 taken 252 times.
✓ Branch 3 taken 54 times.
✓ Branch 4 taken 252 times.
✗ Branch 5 not taken.
684 else if(wpn && wpn!=ewBrang && dmisc2==e2tFIREOCTO) // Fire Octo
13050 {
13051 if(!dummy_bool[0])
13052 {
13053 int32_t wpn2 = wpn+dmisc3;
13054
13055 if(wpn2 <= wEnemyWeapons || wpn2 >= wMax)
13056 {
13057 wpn2=wpn;
13058 }
13059
13060 dummy_bool[0]=true;
13061 addEwpn(x,y,z,wpn2,0,dmisc4,up, getUID(), 0, fakez);
13062 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13063 addEwpn(x,y,z,wpn2,0,dmisc4,down, getUID(), 0, fakez);
13064 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13065 addEwpn(x,y,z,wpn2,0,dmisc4,left, getUID(), 0, fakez);
13066 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13067 addEwpn(x,y,z,wpn2,0,dmisc4,right, getUID(), 0, fakez);
13068 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13069 addEwpn(x,y,z,wpn2,0,dmisc4,l_up, getUID(), 0, fakez);
13070 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13071 addEwpn(x,y,z,wpn2,0,dmisc4,r_up, getUID(), 0, fakez);
13072 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13073 addEwpn(x,y,z,wpn2,0,dmisc4,l_down, getUID(), 0, fakez);
13074 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13075 addEwpn(x,y,z,wpn2,0,dmisc4,r_down, getUID(), 0, fakez);
13076 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13077 sfx(wpnsfx(wpn2),pan(int32_t(x)));
13078 }
13079 }
13080
13081 684 KillWeapon();
13082 684 return Dead(index);
13083 }
13084 //vire split
13085 //2.10 checked !fslide(), but nothing uses that now anyway. -Z
13086 //Perhaps the problem occurs when vires die because they have < 0 HP, in this check?
13087
5/14
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 36427 times.
✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 38 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 36465 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
36465 else if(((hp<=0 && !immortal) && dmisc2==e2tSPLIT) || (dmisc2==e2tSPLITHIT && hp>0 && hp<guysbuf[id&0xFFF].hp && !slide() && (sclk&255)<=1)) //Split into enemies
13088 {
13089 stop_bgsfx(index);
13090 int32_t kids = guys.Count();
13091 int32_t id2=dmisc3;
13092 for(int32_t i=0; i < dmisc4; i++)
13093 {
13094 // if (addenemy(x,y,id2+(guysbuf[id2].family==eeKEESE ? 0 : ((i+1)<<12)),-21-(i%4)))
13095 if(addenemy(x,y,id2+(guysbuf[id2].family==eeKEESE ? 0 : ((editorflags & ENEMY_FLAG5) ? 0 : (i<<12))),-21-(i%4)))
13096 ((enemy*)guys.spr(kids+i))->count_enemy = false;
13097 }
13098
13099 if(itemguy) // Hand down the carried item
13100 {
13101 guycarryingitem = guys.Count()-1;
13102 ((enemy*)guys.spr(guycarryingitem))->itemguy = true;
13103 itemguy = false;
13104 }
13105
13106 if(hashero)
13107 {
13108 Hero.setEaten(0);
13109 hashero=false;
13110 }
13111
13112 if(deadsfx > 0 && dmisc2==e2tSPLIT)
13113 sfx(deadsfx,pan(int32_t(x)));
13114
13115 return true;
13116 }
13117 /*
13118 else if((dmisc2==e2tSPLITHIT && (hp<=0 && !immortal) &&!slide())) //Possible vires fix; or could cause goodness knows what. -Z
13119 {
13120 stop_bgsfx(index);
13121 int32_t kids = guys.Count();
13122 int32_t id2=dmisc3;
13123
13124 for(int32_t i=0; i < dmisc4; i++)
13125 {
13126 // if (addenemy(x,y,id2+(guysbuf[id2].family==eeKEESE ? 0 : ((i+1)<<12)),-21-(i%4)))
13127 if(addenemy(x,y,id2+(guysbuf[id2].family==eeKEESE ? 0 : (i<<12)),-21-(i%4)))
13128 ((enemy*)guys.spr(kids+i))->count_enemy = false;
13129 }
13130
13131 if(itemguy) // Hand down the carried item
13132 {
13133 guycarryingitem = guys.Count()-1;
13134 ((enemy*)guys.spr(guycarryingitem))->itemguy = true;
13135 itemguy = false;
13136 }
13137
13138 if(hashero)
13139 {
13140 Hero.setEaten(0);
13141 hashero=false;
13142 }
13143
13144 return true;
13145 }
13146 */
13147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36465 times.
36465 if(fading)
13148 {
13149 if(++clk4 > 60)
13150 {
13151 clk4=0;
13152 superman=0;
13153 fading=0;
13154
13155 if(flags2&cmbflag_armos && z==0 && fakez == 0)
13156 {
13157 //if a custom size (not 16px by 16px)
13158
13159 //if a custom size (not 16px by 16px)
13160 if (ffcactivated)
13161 removearmosffc(ffcactivated-1);
13162 else
13163 {
13164 if (txsz > 1 || tysz > 1 || (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) || (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) )//remove more than one combo based on enemy size
13165 {
13166 //zprint("spawn big enemy from armos\n");
13167 //if removing a block, then adjust y by -1 as the enemy spawns at y+1
13168 for(int32_t dx = 0; dx < tysz; dx ++)
13169 {
13170 for(int32_t dy = 0; dy < tysz; dy++)
13171 {
13172 removearmos((int32_t)x+(dx*16),(int32_t)y+(dy*16)+1);
13173 did_armos = false;
13174 }
13175 removearmos((int32_t)x+(dx*16), (int32_t)y+((tysz-1)*16)+1);
13176 did_armos = false;
13177 }
13178 for(int32_t dy = 0; dy < tysz; dy ++)
13179 {
13180 removearmos((int32_t)x+((txsz-1)*16), (int32_t)y+(dy*16)+1);
13181 did_armos = false;
13182 }
13183 removearmos((int32_t)x+((txsz-1)*16), (int32_t)y+((tysz-1)*16)+1);
13184 }
13185 else removearmos(x,y);
13186 }
13187 /*
13188 if (txsz > 1 || tysz > 1 || (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) || (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) )//remove more than one combo based on enemy size
13189 {
13190 //if removing a block, then adjust y by -1 as the enemy spawns at y+1
13191 for(int32_t dx = 0; dx < hxsz; dx += 16)
13192 {
13193 for(int32_t dy = 0; dy < hysz; dy += 16)
13194 {
13195 removearmos((int32_t)x+dx+hxofs,(int32_t)y+dy+hyofs+1,ffcactivated);
13196 did_armos = false;
13197 }
13198 removearmos((int32_t)x+dx+hxofs, (int32_t)y+hyofs+(hysz-1)-1,ffcactivated);
13199 did_armos = false;
13200 }
13201 for(int32_t dy = 0; dy < hysz; dy += 16)
13202 {
13203 removearmos((int32_t)x+hxofs+(hxsz-1), (int32_t)y+dy+hyofs-1,ffcactivated);
13204 did_armos = false;
13205 }
13206 removearmos((int32_t)x+hxofs+(hxsz-1), (int32_t)y+hyofs+(hysz-1)-1,ffcactivated);
13207 }
13208 else removearmos(x,y,ffcactivated);
13209 */
13210
13211 }
13212
13213 clk2=0;
13214
13215 newdir();
13216 }
13217 else return enemy::animate(index);
13218 }
13219
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 36465 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
36465 else if(flags2&cmbflag_armos && z==0 && fakez == 0 && clk==0)
13220 removearmos(x,y,ffcactivated);
13221
13222
13223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36465 times.
36465 if(hashero)
13224 {
13225 Hero.setX(x);
13226 Hero.setY(y);
13227 ++clk2;
13228
13229 if(clk2==(dmisc8==0 ? 95 : dmisc8))
13230 {
13231 switch(dmisc7)
13232 {
13233 case e7tEATITEMS:
13234 {
13235 for(int32_t i=0; i<MAXITEMS; i++)
13236 {
13237 if(itemsbuf[i].flags&ITEM_EDIBLE)
13238 game->set_item(i, false);
13239 }
13240
13241 break;
13242 }
13243
13244 case e7tEATMAGIC:
13245 game->change_dmagic(-1*game->get_magicdrainrate());
13246 break;
13247
13248 case e7tEATRUPEES:
13249 game->change_drupy(-1);
13250 break;
13251 }
13252
13253 clk2=0;
13254 }
13255
13256 if((clk&0x18)==8) // stop its animation on the middle frame
13257 --clk;
13258 }
13259
4/4
✓ Branch 0 taken 1470 times.
✓ Branch 1 taken 34995 times.
✓ Branch 2 taken 626 times.
✓ Branch 3 taken 844 times.
36465 else if(!(wpn==ewBrang && WeaponOut())) //WeaponOut uses misc
13260 {
13261 // Movement engine
13262
3/6
✓ Branch 0 taken 2358 times.
✓ Branch 1 taken 33263 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 33263 times.
✗ Branch 5 not taken.
35621 if(clk>=0) switch(id>>12)
13263 {
13264 case 0: // Normal movement
13265
13266 /*
13267 if((dmisc9==e9tLEEVER || dmisc9==e9tZ3LEEVER) && !slide()) //Leever
13268 {
13269 // Overloading clk4 (Tribble clock) here...
13270 step=17/100.0;
13271 if(clk4<32) misc=1;
13272 else if(clk4<48) misc=2;
13273 else if(clk4<300) { misc=3; step = dstep/100.0; }
13274 else if(clk4<316) misc=2;
13275 else if(clk4<412) misc=1;
13276 else if(clk4<540) { misc=0; step=0; }
13277 else clk4=0;
13278 if(clk4==48) clk=0;
13279 hxofs=(misc>=2)?0:1000;
13280 if (dmisc9==e9tLEEVER)
13281 variable_walk(rate, homing, 0);
13282 else
13283 variable_walk_8(rate, homing, 4, 0);
13284 break;
13285 }
13286 */
13287
2/4
✓ Branch 0 taken 33263 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 33263 times.
33263 if(dmisc9==e9tVIRE || dmisc9==e9tPOLSVOICE) //Vire
13288 {
13289 vire_hop();
13290 break;
13291 }
13292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33263 times.
33263 else if(dmisc9==e9tROPE) //Rope charge
13293 {
13294 if(!fired && dashing && !stunclk && !watch && !frozenclock)
13295 {
13296 if(dmisc2==e2tBOMBCHU && HeroInRange(16) && wpn+dmisc3 > wEnemyWeapons) //Bombchu
13297 {
13298
13299 if ( get_bit(quest_rules,qr_BOMBCHUSUPERBOMB) )
13300 {
13301 hp=-1000;
13302
13303 if(wpn+dmisc3 > wEnemyWeapons && wpn+dmisc3 < wMax)
13304 {
13305 weapon *ew=new weapon(x,y,z, wpn+dmisc3, 0, dmisc4, dir,-1,getUID());
13306 Ewpns.add(ew);
13307 ew->fakez = fakez;
13308
13309 if(wpn==ewSBomb || wpn==ewBomb)
13310 {
13311 ew->step=0;
13312 ew->id=wpn+dmisc3;
13313 ew->misc=50;
13314 ew->clk=48;
13315 }
13316
13317 fired=true;
13318 }
13319 else
13320 {
13321 weapon *ew=new weapon(x,y,z, wpn, 0, dmisc4, dir,-1,getUID());
13322 Ewpns.add(ew);
13323 ew->fakez = fakez;
13324
13325 if(wpn==ewSBomb || wpn==ewBomb)
13326 {
13327 ew->step=0;
13328 ew->id=wpn;
13329 ew->misc=50;
13330 ew->clk=48;
13331 }
13332
13333 fired=true;
13334 }
13335 }
13336
13337 else
13338 {
13339 hp=-1000;
13340
13341 int32_t wpn2;
13342 if(wpn+dmisc3 > wEnemyWeapons && wpn+dmisc3 < wMax)
13343 wpn2=wpn;
13344 else
13345 wpn2=wpn;
13346
13347 weapon *ew=new weapon(x,y,z, wpn2, 0, dmisc4, dir,-1,getUID());
13348 Ewpns.add(ew);
13349 ew->fakez = fakez;
13350
13351 if(wpn2==ewSBomb || wpn2==ewBomb)
13352 {
13353 ew->step=0;
13354 ew->id=wpn2;
13355 ew->misc=50;
13356 ew->clk=48;
13357 }
13358
13359 fired=true;
13360 }
13361 }
13362 }
13363
13364 charge_attack();
13365 break;
13366 }
13367 /*
13368 * Boomerang-throwers have a halt count of 1
13369 * Zols have a halt count of (zc_oldrand()&7)<<4
13370 * Gels have a halt count of ((zc_oldrand()&7)<<3)+2
13371 * Everything else has 48
13372 */
13373 else
13374 {
13375
2/2
✓ Branch 0 taken 578 times.
✓ Branch 1 taken 32685 times.
33263 if(wpn==ewBrang) // Goriya
13376 {
13377 578 halting_walk(rate,homing,0,hrate, 1);
13378 578 }
13379
3/4
✓ Branch 0 taken 32685 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3321 times.
✓ Branch 3 taken 29364 times.
32685 else if(dmisc9==e9tNORMAL && wpn==0)
13380 {
13381
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29364 times.
29364 if(dmisc2==e2tSPLITHIT) // Zol
13382 {
13383 halting_walk(rate,homing,0,hrate,(zc_oldrand()&7)<<4);
13384 }
13385
3/4
✓ Branch 0 taken 1519 times.
✓ Branch 1 taken 27845 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1519 times.
29364 else if(frate<=8 && starting_hp==1) // Gel
13386 {
13387 1519 halting_walk(rate,homing,0,hrate,((zc_oldrand()&7)<<3)+2);
13388 1519 }
13389 else // Other
13390 {
13391 27845 halting_walk(rate,homing,0,hrate, 48);
13392 }
13393 29364 }
13394 else // Other
13395 {
13396 3321 halting_walk(rate,homing,0,hrate, 48);
13397 }
13398 }
13399
13400 //if not in midair, and Hero's swinging sword is nearby, jump.
13401 /*if (dmisc9==e9tZ3STALFOS && z==0 && (!(isSideViewGravity()) || !_walkflag(x,y+16,0))
13402 && Hero.getAttackClk()==5 && Hero.getAttack()==wSword && distance(x,y,Hero.getX(),Hero.getY())<32)
13403 {
13404 facehero(false);
13405 sclk=16+((dir^1)<<8);
13406 fall=-FEATHERJUMP;
13407 sfx(WAV_ZN1JUMP,pan(int32_t(x)));
13408 }*/
13409 33263 break;
13410
13411 // Following cases are for just after creation-by-splitting.
13412 case 1:
13413 if(misc==1)
13414 {
13415 dir=up;
13416 step=8;
13417 }
13418
13419 if(misc<=2)
13420 {
13421 move(step);
13422
13423 if(!canmove(dir,(zfix)0,0,false))
13424 dir=down;
13425 }
13426
13427 if(misc==3)
13428 {
13429 if(canmove(right,(zfix)16,0,false))
13430 x+=16;
13431 }
13432
13433 ++misc;
13434 break;
13435
13436 case 2:
13437 if(misc==1)
13438 {
13439 dir=down;
13440 step=8;
13441 }
13442
13443 if(misc<=2)
13444 {
13445 move(step);
13446 /*
13447 if(!canmove(dir,(zfix)0,0,false))
13448 dir=up;
13449 */
13450 }
13451
13452 if(misc==3)
13453 {
13454 if(canmove(left,(zfix)16,0,false))
13455 x-=16;
13456 }
13457
13458 ++misc;
13459 break;
13460
13461 default:
13462 if(misc==1)
13463 {
13464 dir=(zc_oldrand()%4);
13465 step=8;
13466 }
13467
13468 if(misc<=2)
13469 {
13470 move(step);
13471
13472 if(!canmove(dir,(zfix)0,0,false))
13473 dir=dir^1;
13474 }
13475
13476 if(misc==3)
13477 {
13478 if(dir >= left && canmove(dir,(zfix)16,0,false))
13479 x+=(dir==left ? -16 : 16);
13480 }
13481
13482 ++misc;
13483 break;
13484 33263 }
13485
13486
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 35621 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
35621 if(id>>12 && misc>=4) //recently spawned by a split enemy
13487 {
13488 id&=0xFFF;
13489 step = zslongToFix(dstep*100);
13490
13491 if(x<32) x=32;
13492
13493 if(x>208) x=208;
13494
13495 if(y<32) y=32;
13496
13497 if(y>128) y=128;
13498
13499 misc=3;
13500 }
13501 35621 }
13502 else
13503 {
13504 //sfx(wpnsfx(wpn),pan(int32_t(x)));
13505
1/2
✓ Branch 0 taken 844 times.
✗ Branch 1 not taken.
844 if(clk2>2) clk2--;
13506 }
13507
13508 // Fire Zol
13509
3/8
✓ Branch 0 taken 5580 times.
✓ Branch 1 taken 30885 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5580 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
36465 if(wpn && dmisc1==e1tEACHTILE && clk2==1 && !hclk)
13510 {
13511 addEwpn(x,y,z,wpn,0,wdp,dir, getUID(), 0, fakez);
13512 sfx(wpnsfx(wpn),pan(int32_t(x)));
13513
13514 int32_t i=Ewpns.Count()-1;
13515 weapon *ew = (weapon*)(Ewpns.spr(i));
13516
13517 if(wpn==ewFIRETRAIL && wpnsbuf[ewFIRETRAIL].frames>1)
13518 {
13519 ew->aframe=zc_oldrand()%wpnsbuf[ewFIRETRAIL].frames;
13520 if ( ew->do_animation ) ew->tile+=ew->aframe;
13521 }
13522 }
13523 // Goriya
13524
12/16
✓ Branch 0 taken 1470 times.
✓ Branch 1 taken 34995 times.
✓ Branch 2 taken 857 times.
✓ Branch 3 taken 613 times.
✓ Branch 4 taken 834 times.
✓ Branch 5 taken 23 times.
✓ Branch 6 taken 834 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 834 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 834 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 834 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 824 times.
✓ Branch 15 taken 10 times.
36465 else if(wpn==ewBrang && clk2==1 && sclk==0 && !stunclk && !frozenclock && !watch && wpn && !WeaponOut())
13525 {
13526 10 misc=index+100;
13527
7/14
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 10 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 10 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 10 times.
✗ Branch 13 not taken.
10 Ewpns.add(new weapon(x,y-fakez,z,wpn,misc,wdp,dir, -1,getUID(),false));
13528 10 ((weapon*)Ewpns.spr(Ewpns.Count()-1))->dummy_bool[0]=false;
13529
13530
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(dmisc1==2)
13531 {
13532 int32_t ndir=dir;
13533
13534 if(Hero.x-x==0)
13535 {
13536 ndir=(Hero.y+8<y)?up:down;
13537 }
13538 else //turn to face Hero
13539 {
13540 double _MSVC2022_tmp1, _MSVC2022_tmp2;
13541 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
13542
13543 if((ddir<=(((-2)*PI)/8))&&(ddir>(((-6)*PI)/8)))
13544 {
13545 ndir=down;
13546 }
13547 else if((ddir<=(((2)*PI)/8))&&(ddir>(((-2)*PI)/8)))
13548 {
13549 ndir=right;
13550 }
13551 else if((ddir<=(((6)*PI)/8))&&(ddir>(((2)*PI)/8)))
13552 {
13553 ndir=up;
13554 }
13555 else
13556 {
13557 ndir=left;
13558 }
13559 }
13560
13561 ((weapon*)Ewpns.spr(Ewpns.Count()-1))->dummy_bool[0]=true;
13562
13563 if(canmove(ndir,false))
13564 {
13565 dir=ndir;
13566 }
13567 }
13568 10 }
13569
11/16
✓ Branch 0 taken 36254 times.
✓ Branch 1 taken 201 times.
✓ Branch 2 taken 201 times.
✓ Branch 3 taken 36254 times.
✓ Branch 4 taken 19 times.
✓ Branch 5 taken 182 times.
✓ Branch 6 taken 19 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 19 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 19 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 19 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 19 times.
36455 else if((clk2==16 || dmisc1==e1tCONSTANT) && dmisc1!=e1tEACHTILE && wpn && wpn!=ewBrang && sclk==0 && !stunclk && !frozenclock && !watch)
13570
1/3
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
19 switch(dmisc1)
13571 {
13572 case e1tCONSTANT: //Deathnut
13573 {
13574 // Overloading clk5 (Like Like clock) to avoid making another clock just for this attack...
13575 if(clk5>64)
13576 {
13577 clk5=0;
13578 fired=false;
13579 }
13580
13581 clk5+=(zc_oldrand()&3);
13582
13583 if((clk5>24)&&(clk5<52))
13584 {
13585 if ( do_animation )tile+=20; //firing
13586
13587 if(!fired&&(clk5>=38))
13588 {
13589 Ewpns.add(new weapon(x,y,z, wpn, 0, wdp, dir, -1,getUID(),false));
13590 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
13591 sfx(wpnsfx(wpn),pan(int32_t(x)));
13592 fired=true;
13593 }
13594 }
13595
13596 break;
13597 }
13598
13599 case e1tFIREOCTO: //Fire Octo
13600 timer=zc_oldrand()%50+50;
13601 break;
13602
13603 default:
13604 19 FireWeapon();
13605 19 break;
13606 19 }
13607
13608 /* Fire again if:
13609 * - clk2 about to run out
13610 * - not already double-firing (dmisc1 is 1)
13611 * - not carrying Hero
13612 * - one in 0xF chance
13613 */
13614
3/10
✓ Branch 0 taken 1061 times.
✓ Branch 1 taken 35404 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1061 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
36465 if(clk2==1 && (multishot < dmisc6) && dmisc1 != e1tEACHTILE && !hashero && !(zc_oldrand()&15))
13615 {
13616 #if 1
13617 newdir(rate, homing, grumble);
13618 #else
13619 dir^=2;
13620 #endif
13621 clk2=28;
13622 ++multishot;
13623 }
13624
13625
2/2
✓ Branch 0 taken 10372 times.
✓ Branch 1 taken 26093 times.
36465 if(clk2==0)
13626 {
13627 26093 multishot = 0;
13628 26093 }
13629
13630
1/2
✓ Branch 0 taken 36465 times.
✗ Branch 1 not taken.
36465 if(timer) //Fire Octo
13631 {
13632 clk2=15; //this keeps the octo in place until he's done firing
13633
13634 if(!(timer%4))
13635 {
13636 FireBreath(false);
13637 }
13638
13639 --timer;
13640 }
13641
13642
1/2
✓ Branch 0 taken 36465 times.
✗ Branch 1 not taken.
36465 if(dmisc2==e2tTRIBBLE)
13643 ++clk4;
13644
13645
2/10
✗ Branch 0 not taken.
✓ Branch 1 taken 36465 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 36465 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
36465 if(clk4==(dmisc5 ? dmisc5 : 256) && (dmisc2==e2tTRIBBLE) && dmisc3 && dmisc4)
13646 {
13647 int32_t kids = guys.Count();
13648 int32_t id2=dmisc3;
13649
13650 for(int32_t i=0; i<dmisc4; i++)
13651 {
13652 if(addenemy(x,y,id2,-24))
13653 {
13654 if(itemguy) // Hand down the carried item
13655 {
13656 guycarryingitem = guys.Count()-1;
13657 ((enemy*)guys.spr(guycarryingitem))->itemguy = true;
13658 itemguy = false;
13659 }
13660
13661 ((enemy*)guys.spr(kids+i))->count_enemy = false;
13662 }
13663 }
13664
13665 if(hashero)
13666 {
13667 Hero.setEaten(0);
13668 hashero=false;
13669 }
13670
13671 stop_bgsfx(index);
13672 return true;
13673 }
13674
13675 36465 return enemy::animate(index);
13676 37149 }
13677
13678 37158 void eStalfos::draw(BITMAP *dest)
13679 {
13680 /*if ((dmisc9==e9tLEEVER || dmisc9==e9tZ3LEEVER) && misc<=0) //Submerged
13681 {
13682 clk4--; //Kludge
13683 return;
13684 }*/
13685
13686 /*if ((dmisc9==e9tLEEVER || dmisc9==e9tZ3LEEVER) && misc>1)
13687 {
13688 cs = dcset;
13689 }*/
13690 37158 update_enemy_frame();
13691
13692
3/8
✓ Branch 0 taken 37158 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37158 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 37158 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
37158 if(!fallclk&&!drownclk&&(dmisc2==e2tBOMBCHU)&&dashing)
13693 {
13694 if ( do_animation )tile+=20;
13695 }
13696
13697 37158 enemy::draw(dest);
13698 37158 }
13699
13700 23619 void eStalfos::drawshadow(BITMAP *dest, bool translucent)
13701 {
13702 23619 int32_t tempy=yofs;
13703
13704 /*
13705 if (clk6 && dir>=left && !get_bit(quest_rules,qr_ENEMIESZAXIS)) {
13706 flip = 0;
13707 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
13708 (clk/(frate/4)):((clk>=(frate>>1))?1:0);
13709 shadowtile = wpnsbuf[spr_shadow].tile+f2;
13710 yofs+=(((int32_t)y+17)&0xF0)-y;
13711 yofs+=8;
13712 }
13713 */
13714
2/4
✓ Branch 0 taken 23619 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23619 times.
✗ Branch 3 not taken.
23619 if((dmisc9 == e9tPOLSVOICE || dmisc9==e9tVIRE) && !get_bit(quest_rules,qr_ENEMIESZAXIS))
13715 {
13716 flip = 0;
13717 int32_t fdiv = frate/4;
13718 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
13719
13720 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
13721 efrate:((clk>=(frate>>1))?1:0);
13722 shadowtile = wpnsbuf[spr_shadow].tile;
13723
13724 if(get_bit(quest_rules,qr_NEWENEMYTILES))
13725 {
13726 shadowtile+=f2;
13727 }
13728 else
13729 {
13730 shadowtile+=f2?1:0;
13731 }
13732
13733 yofs+=shadowdistance;
13734 yofs+=8;
13735 }
13736
2/4
✓ Branch 0 taken 23619 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23619 times.
✗ Branch 3 not taken.
23619 if((dmisc9 == e9tPOLSVOICE || dmisc9==e9tVIRE) && !get_bit(quest_rules,qr_POLVIRE_NO_SHADOW))
13737 {
13738 flip = 0;
13739 int32_t fdiv = frate/4;
13740 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
13741
13742 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
13743 efrate:((clk>=(frate>>1))?1:0);
13744 shadowtile = wpnsbuf[spr_shadow].tile;
13745
13746 if(get_bit(quest_rules,qr_NEWENEMYTILES))
13747 {
13748 shadowtile+=f2;
13749 }
13750 else
13751 {
13752 shadowtile+=f2?1:0;
13753 }
13754 }
13755
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23619 times.
23619 if(!shadow_overpit(this))
13756 23619 enemy::drawshadow(dest, translucent);
13757 23619 yofs=tempy;
13758 23619 }
13759
13760 57 int32_t eStalfos::takehit(weapon *w)
13761 {
13762 57 int32_t wpnId = w->id;
13763 57 int32_t wpnDir = w->dir;
13764
13765
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
57 if(wpnId==wHammer && shield && (flags & guy_bkshield)
13766 && ((flags&inv_front && wpnDir==(dir^down)) || (flags&inv_back && wpnDir==(dir^up))
13767 || (flags&inv_left && wpnDir==(dir^left)) || (flags&inv_right && wpnDir==(dir^right))))
13768 {
13769 shield = false;
13770 flags &= ~(inv_left|inv_right|inv_back|inv_front);
13771
13772 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
13773 o_tile=s_tile;
13774 }
13775
13776 57 int32_t ret = enemy::takehit(w);
13777
13778
3/4
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
57 if(sclk && dmisc2==e2tSPLITHIT)
13779 sclk+=128; //Fuck these arbitrary values with no explanation. Fuck vires, too. -Z
13780
13781 57 return ret;
13782 }
13783
13784 void eStalfos::charge_attack()
13785 {
13786 if(slide())
13787 return;
13788
13789 if(clk<0 || dir<0 || stunclk || watch || ceiling || frozenclock )
13790 return;
13791
13792 if(clk3<=0)
13793 {
13794 fix_coords(true);
13795
13796 if(!dashing)
13797 {
13798 int32_t ldir = lined_up(7,false);
13799
13800 if(ldir!=-1 && canmove(ldir,false))
13801 {
13802 dir=ldir;
13803 dashing=true;
13804 step=zslongToFix(dstep*100)+1;
13805 }
13806 else newdir(4,0,0);
13807 }
13808
13809 if(!canmove(dir,false))
13810 {
13811 step=zslongToFix(dstep*100);
13812 newdir();
13813 dashing=false;
13814 }
13815
13816 zfix div = step;
13817
13818 if(div == 0)
13819 div = 1;
13820
13821 clk3=(int32_t)(16.0/div);
13822 return;
13823 }
13824
13825 move(step);
13826 --clk3;
13827 }
13828
13829 void eStalfos::vire_hop()
13830 {
13831 //if ( sclk > 0 ) return; //Don't hop during knockback.
13832
13833 // if(dmisc9!=e9tPOLSVOICE)
13834 // {
13835 // //if( slide() /*sclk!=0*/ && dmisc2==e2tSPLIT) //Vires with split on hit, only! -Z
13836 // if( sclk!=0 && dmisc2==e2tSPLIT) //Vires with split on hit, only! -Z
13837 // return; //the enemy should split if it is sliding!
13838 // //else sclk=0; //might need this here, too. -Z
13839 // }
13840 if(dmisc9!=e9tPOLSVOICE)
13841 {
13842 if(sclk!=0)
13843 {
13844 if (dmisc2==e2tSPLITHIT) return;
13845 //return;
13846 }
13847 }
13848 else sclk=0;
13849
13850 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
13851 return;
13852
13853 int32_t jump_width = (dmisc9==e9tPOLSVOICE) ? 2 : 1;
13854 int32_t jump_height = (dmisc9==e9tPOLSVOICE) ? 27 : 16;
13855
13856 y=floor_y;
13857
13858 if(clk3<=0)
13859 {
13860 fix_coords();
13861
13862 //z=0;
13863 //if we're not in the middle of a jump or if we can't complete the current jump in the current direction
13864 //if(clk2<=0 || !canmove(dir,(zfix)1,spw_floater,false) || (isSideViewGravity() && isOnSideviewPlatform()))
13865 if(clk2<=0 || !canmove(dir,(zfix)1,spw_floater,false) || (isSideViewGravity() && (isOnSideviewPlatform() || !(moveflags & FLAG_OBEYS_GRAV)))) //Vires in old quests
13866 newdir(rate,homing,dmisc9==e9tPOLSVOICE ? spw_floater : spw_none);
13867
13868 if(clk2<=0)
13869 {
13870 //z=0;
13871 if(!canmove(dir,(zfix)2,spw_none,false) || m_walkflag(x,y,spw_none, dir) || (zc_oldrand()&15)>=hrate)
13872 {
13873
13874 clk2=(wpn==ewBrang ? 1 : int32_t((16.0*jump_width)/step.getFloat()));
13875 /*if (dmisc9==e9tPOLSVOICE )
13876 {
13877 zprint2("polsvoice jump_width is: %d\n", jump_width);
13878 zprint2("polsvoice raw step is: %d\n", step);
13879 zprint2("polsvoice step.getInt() is: %d\n", step.getInt());
13880 zprint2("setting clk2 on polsvoice to: %d\n", clk2);
13881 }
13882 else
13883 {
13884 zprint2("vire jump_width is: %d\n", jump_width);
13885 zprint2("vire raw step is: %d\n", step);
13886 zprint2("vire step.getInt() is: %d\n", step.getInt());
13887 zprint2("setting clk2 on vire to: %d\n", clk2);
13888 }
13889 */
13890 }
13891 }
13892
13893 if(dmisc9!=e9tPOLSVOICE && dir>=left) //if we're moving left or right
13894 {
13895 clk2=int32_t((16.0*jump_width)/step.getFloat());
13896 }
13897
13898 clk3=int32_t(16.0/step.getFloat());
13899 }
13900
13901 --clk3;
13902
13903 if(dmisc9==e9tPOLSVOICE || clk2>0)
13904 move(step);
13905
13906 floor_y=y;
13907 clk2--;
13908
13909 //if we're in the middle of a jump
13910 if(clk2>0 && (dir>=left || dmisc9==e9tPOLSVOICE))
13911 {
13912 int32_t h = fixtoi(fixsin(itofix(clk2*128*step/(16*jump_width)))*jump_height);
13913
13914 if(get_bit(quest_rules,qr_ENEMIESZAXIS) && !(isSideViewGravity()))
13915 {
13916 if (moveflags & FLAG_USE_FAKE_Z) fakez=h;
13917 else z=h;
13918 }
13919 else
13920 {
13921 //y+=fixtoi(fixsin(itofix((clk2+1)*128*step/(16*jump_width)))*jump_height);
13922 //y-=h;
13923 y=floor_y-h;
13924 shadowdistance=h;
13925 }
13926 }
13927 else
13928 shadowdistance = 0;
13929 }
13930
13931 void eStalfos::eathero()
13932 {
13933 if(!hashero && Hero.getEaten()==0 && Hero.getAction() != hopping && Hero.getAction() != swimming)
13934 {
13935 hashero=true;
13936 y=floor_y;
13937 z=0;
13938
13939 if(Hero.isSwimming())
13940 {
13941 Hero.setX(x);
13942 Hero.setY(y);
13943 }
13944 else
13945 {
13946 x=Hero.getX();
13947 y=Hero.getY();
13948 }
13949
13950 clk2=0;
13951 }
13952 }
13953
13954 2304 bool eStalfos::WeaponOut()
13955 {
13956
2/2
✓ Branch 0 taken 2798 times.
✓ Branch 1 taken 636 times.
3434 for(int32_t i=0; i<Ewpns.Count(); i++)
13957 {
13958
3/4
✓ Branch 0 taken 1668 times.
✓ Branch 1 taken 1130 times.
✓ Branch 2 taken 1668 times.
✗ Branch 3 not taken.
2798 if(((weapon*)Ewpns.spr(i))->parentid==getUID() && Ewpns.spr(i)->id==ewBrang)
13959 {
13960 1668 return true;
13961 }
13962
13963 /*if (bgsfx > 0 && guys.idCount(id) < 2) // count self
13964 stop_sfx(bgsfx);
13965 */
13966 1130 }
13967
13968 636 return false;
13969 2304 }
13970
13971 684 void eStalfos::KillWeapon()
13972 {
13973
2/2
✓ Branch 0 taken 684 times.
✓ Branch 1 taken 189 times.
873 for(int32_t i=0; i<Ewpns.Count(); i++)
13974 {
13975
4/4
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 161 times.
✓ Branch 3 taken 1 times.
189 if(((weapon*)Ewpns.spr(i))->type==misc && Ewpns.spr(i)->id==ewBrang)
13976 {
13977 //only kill this Goriya's boomerang -DD
13978
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(((weapon *)Ewpns.spr(i))->parentid == getUID())
13979 {
13980 1 Ewpns.del(i);
13981 1 }
13982 1 }
13983 189 }
13984
13985
4/4
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 630 times.
✓ Branch 2 taken 31 times.
✓ Branch 3 taken 23 times.
684 if(wpn==ewBrang && !Ewpns.idCount(ewBrang))
13986 {
13987 31 stop_sfx(WAV_BRANG);
13988 31 }
13989 684 }
13990
13991 void eStalfos::break_shield()
13992 {
13993 if(!shield)
13994 return;
13995
13996 flags&=~(inv_front | inv_back | inv_left | inv_right);
13997 shield=false;
13998
13999 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
14000 o_tile=s_tile;
14001 }
14002
14003 51 eKeese::eKeese(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
14004 51 {
14005
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 dir=(zc_oldrand()&7)+8;
14006
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 step=0;
14007 17 movestatus=1;
14008
2/4
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
17 if (dmisc1 != 1 && dmisc19 > 0)
14009 {
14010 step = dmisc19/100.0;
14011 movestatus = 1;
14012 }
14013
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 if (dmisc1 == 2) movestatus=2;
14014 17 c=0;
14015 17 SIZEflags = d->SIZEflags;
14016
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if ( !(SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) ) hxofs=2;
14017
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
14018
14019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if ( !(SIZEflags&guyflagOVERRIDE_HIT_WIDTH) ) hxsz=12;
14020
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
14021
14022
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if ( !(SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) ) hyofs=4;
14023
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
14024
14025
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if ( !(SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) ) hysz=8;
14026
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && d->hysz >= 0 ) hysz = d->hysz;
14027
14028
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
17 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && d->txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
14029 //al_trace("->txsz:%i\n", d->txsz); Verified that this is setting the value. -Z
14030 // al_trace("Enemy txsz:%i\n", txsz);
14031
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
17 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && d->tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
14032
14033
14034
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && d->hzsz >= 0 ) hzsz = d->hzsz;
14035
14036
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
14037
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
14038 {
14039 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
14040 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
14041 }
14042
14043
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
14044 17 clk4=0;
14045 //nets;
14046 17 dummy_int[1]=0;
14047 34 }
14048
14049 1923 bool eKeese::animate(int32_t index)
14050 {
14051
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1923 times.
1923 if(switch_hooked) return enemy::animate(index);
14052
2/4
✓ Branch 0 taken 1923 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1923 times.
1923 if(fallclk||drownclk) return enemy::animate(index);
14053
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 1846 times.
1923 if(dying)
14054 77 return Dead(index);
14055
14056
2/2
✓ Branch 0 taken 1829 times.
✓ Branch 1 taken 17 times.
1846 if(clk==0)
14057 {
14058 17 removearmos(x,y,ffcactivated);
14059 17 }
14060
14061
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1846 times.
1846 if(dmisc1 == 1) //Walk style. 0 is keese, 1 is bat.
14062 {
14063 floater_walk(rate,hrate,dstep/100,(zfix)0,10,dmisc16,dmisc17);
14064 }
14065 else
14066 {
14067
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1846 times.
1846 if (dmisc18) floater_walk(rate,hrate,dstep/100,dmisc18/100.0,-1,dmisc16,dmisc17);
14068 1846 else floater_walk(rate,hrate,dstep/100,dstep/1000,10,dmisc16,dmisc17);
14069 }
14070
14071
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1846 times.
1846 if(dmisc2 == e2tKEESETRIB)
14072 {
14073 if(++clk4==(dmisc20>0?dmisc20:256))
14074 {
14075 if(!m_walkflag(x,y,0, dir))
14076 {
14077 int32_t kids = guys.Count();
14078 bool success = false;
14079 int32_t id2=dmisc3;
14080 success = 0 != addenemy((zfix)x,(zfix)y,id2,-24);
14081
14082 if(success)
14083 {
14084 if(itemguy) // Hand down the carried item
14085 {
14086 guycarryingitem = guys.Count()-1;
14087 ((enemy*)guys.spr(guycarryingitem))->itemguy = true;
14088 itemguy = false;
14089 }
14090
14091 ((enemy*)guys.spr(kids))->count_enemy = count_enemy;
14092 }
14093
14094 stop_bgsfx(index);
14095 return true;
14096 }
14097 else
14098 {
14099 clk4=0;
14100 }
14101 }
14102 }
14103 // Keese Tribbles stay on the ground, so there's no problem when they transform.
14104
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1846 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1846 else if(get_bit(quest_rules,qr_ENEMIESZAXIS) && !(isSideViewGravity()))
14105 {
14106 if (get_bit(quest_rules,qr_OLD_KEESE_Z_AXIS))
14107 {
14108 if (moveflags & FLAG_USE_FAKE_Z)
14109 {
14110 fakez=int32_t(step/zslongToFix(dstep*100));
14111 // Some variance in keese flight heights when away from Hero
14112 fakez+=int32_t(step*zc_max(zfix(0),(distance(x,y,HeroX(),HeroY())-128)/10));
14113
14114 }
14115 else
14116 {
14117 z=int32_t(step/zslongToFix(dstep*100));
14118 // Some variance in keese flight heights when away from Hero
14119 z+=int32_t(step*zc_max(zfix(0),(distance(x,y,HeroX(),HeroY())-128)/10));
14120 }
14121 }
14122 else
14123 {
14124 if (moveflags & FLAG_USE_FAKE_Z)
14125 {
14126 fakez=int32_t(step/zslongToFix(dstep*100));
14127 // Some variance in keese flight heights when away from Hero
14128 fakez+=int32_t(step*zc_max(zfix(0),(distance(x,y,HeroX(),HeroY())-40)/4));
14129
14130 }
14131 else
14132 {
14133 z=int32_t(step/zslongToFix(dstep*100));
14134 // Some variance in keese flight heights when away from Hero
14135 z+=int32_t(step*zc_max(zfix(0),(distance(x,y,HeroX(),HeroY())-40)/4));
14136 }
14137 }
14138 }
14139
14140 1846 return enemy::animate(index);
14141 1923 }
14142
14143 void eKeese::drawshadow(BITMAP *dest, bool translucent)
14144 {
14145 int32_t tempy=yofs;
14146 flip = 0;
14147 shadowtile = wpnsbuf[spr_shadow].tile+posframe;
14148
14149 yofs+=zc_min(int32_t(step/zslongToFix(dstep*10)), 8);
14150 if(!get_bit(quest_rules,qr_ENEMIESZAXIS))
14151 {
14152 yofs+=int32_t(step/zslongToFix(dstep*10));
14153 }
14154
14155 if(!shadow_overpit(this) && (!get_bit(quest_rules,qr_ENEMIESZAXIS) || step > 0))
14156 enemy::drawshadow(dest, translucent);
14157 yofs=tempy;
14158 }
14159
14160 3846 void eKeese::draw(BITMAP *dest)
14161 {
14162 3846 update_enemy_frame();
14163 3846 enemy::draw(dest);
14164 3846 }
14165
14166 void eWizzrobe::submerge(bool set)
14167 {
14168 if(get_bit(quest_rules,qr_OLD_WIZZROBE_SUBMERGING))
14169 {
14170 hxofs = set?1000:0;
14171 return;
14172 }
14173 if(submerged == set) return;
14174 submerged = set;
14175 if(set)
14176 hxofs+=1000;
14177 else hxofs -= 1000;
14178 }
14179 eWizzrobe::eWizzrobe(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
14180 {
14181 hxofs = 0;
14182 submerged = false;
14183 switch(dmisc1)
14184 {
14185 case 0:
14186 submerge(true);
14187 fading=fade_invisible;
14188 // Set clk to just before the 'reappear' threshold
14189 clk=zc_min(clk+(146+zc_max(0,dmisc5))+14,(146+zc_max(0,dmisc5))-1);
14190 break;
14191
14192 default:
14193 dir=(loadside==right)?right:left;
14194 misc=-3;
14195 break;
14196 }
14197
14198 //netst+2880;
14199 charging=false;
14200 firing=false;
14201 fclk=0;
14202 if(!dmisc1) frate=1200+146; //1200 = 20 seconds
14203 SIZEflags = d->SIZEflags;
14204 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && d->txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
14205 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
14206 // al_trace("Enemy txsz:%i\n", txsz);
14207 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && d->tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
14208 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
14209 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && d->hysz >= 0 ) hysz = d->hysz;
14210 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && d->hzsz >= 0 ) hzsz = d->hzsz;
14211 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 )
14212 {
14213 hxofs = (submerged?hxofs:0)+d->hxofs;
14214 }
14215 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
14216 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
14217 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
14218 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
14219 {
14220 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
14221 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
14222 }
14223
14224 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
14225 }
14226
14227 bool eWizzrobe::animate(int32_t index)
14228 {
14229 if(switch_hooked) return enemy::animate(index);
14230 if(fallclk||drownclk) return enemy::animate(index);
14231 if(dying)
14232 {
14233 return Dead(index);
14234 }
14235
14236 if(clk==0)
14237 {
14238 removearmos(x,y,ffcactivated);
14239 }
14240
14241 if(dmisc1) // Floating
14242 {
14243 wizzrobe_attack();
14244 }
14245 else // Teleporting
14246 {
14247 if(watch || (!get_bit(quest_rules, qr_WIZZROBES_DONT_OBEY_STUN) && stunclk))
14248 {
14249 fading=0;
14250 submerge(false);
14251 solid_update(false);
14252 }
14253 else switch(clk)
14254 {
14255 case 0:
14256 if(!dmisc2)
14257 {
14258 // Wizzrobe Misc4 controls whether wizzrobes can teleport on top of solid combos,
14259 // but should not appear on dungeon walls.
14260 if ( FFCore.getQuestHeaderInfo(vZelda) <= 0x190 ) place_on_axis(true, false); //1.84, and probably 1.90 wizzrobes should NEVER appear in dungeon walls.-Z (1.84 confirmed, 15th January, 2019 by Chris Miller).
14261 else if (editorflags&ENEMY_FLAG5)
14262 {
14263 //2.10 Windrobe
14264 //randomise location and face Hero
14265 int32_t t=0;
14266 bool placed=false;
14267
14268 while(!placed && t<160)
14269 {
14270 if(isdungeon())
14271 {
14272 x=((zc_oldrand()%12)+2)*16;
14273 y=((zc_oldrand()%7)+2)*16;
14274 }
14275 else
14276 {
14277 x=((zc_oldrand()%14)+1)*16;
14278 y=((zc_oldrand()%9)+1)*16;
14279 }
14280
14281 if(!m_walkflag(x,y,spw_door, dir)&&((abs(x-Hero.getX())>=32)||(abs(y-Hero.getY())>=32)))
14282 {
14283 placed=true;
14284 }
14285
14286 ++t;
14287 }
14288
14289 if(abs(x-Hero.getX())<abs(y-Hero.getY()))
14290 {
14291 if(y<Hero.getY())
14292 {
14293 dir=down;
14294 }
14295 else
14296 {
14297 dir=up;
14298 }
14299 }
14300 else
14301 {
14302 if(x<Hero.getX())
14303 {
14304 dir=right;
14305 }
14306 else
14307 {
14308 dir=left;
14309 }
14310 }
14311
14312 if(!placed) // can't place him, he's gone
14313 return true;
14314
14315
14316 //wizzrobe_attack(); //Complaint about 2.10 Windrobes not behaving as they did in 2.10. Let's try it this way. -Z
14317 //wizzrobe_attack_for_real(); //doing this makes them fire twice. The rest is correct.
14318 }
14319 else place_on_axis(true, dmisc4!=0);
14320 }
14321 else
14322 {
14323 int32_t t=0;
14324 bool placed=false;
14325
14326 while(!placed && t<160)
14327 {
14328 if(isdungeon())
14329 {
14330 x=((zc_oldrand()%12)+2)*16;
14331 y=((zc_oldrand()%7)+2)*16;
14332 }
14333 else
14334 {
14335 x=((zc_oldrand()%14)+1)*16;
14336 y=((zc_oldrand()%9)+1)*16;
14337 }
14338
14339 if(!m_walkflag(x,y,spw_door, dir)&&((abs(x-Hero.getX())>=32)||(abs(y-Hero.getY())>=32)))
14340 {
14341 placed=true;
14342 }
14343
14344 ++t;
14345 }
14346
14347 if(abs(x-Hero.getX())<abs(y-Hero.getY()))
14348 {
14349 if(y<Hero.getY())
14350 {
14351 dir=down;
14352 }
14353 else
14354 {
14355 dir=up;
14356 }
14357 }
14358 else
14359 {
14360 if(x<Hero.getX())
14361 {
14362 dir=right;
14363 }
14364 else
14365 {
14366 dir=left;
14367 }
14368 }
14369
14370 if(!placed) // can't place him, he's gone
14371 return true;
14372 }
14373
14374 fading=fade_flicker;
14375 submerge(false);
14376 solid_update(false);
14377 break;
14378
14379 case 64:
14380 fading=0;
14381 charging=true;
14382 break;
14383
14384 case 73:
14385 charging=false;
14386 firing=40;
14387 break;
14388
14389 case 83:
14390 wizzrobe_attack_for_real();
14391 break;
14392
14393 case 119:
14394 firing=false;
14395 charging=true;
14396 break;
14397
14398 case 128:
14399 fading=fade_flicker;
14400 charging=false;
14401 break;
14402
14403 case 146:
14404 fading=fade_invisible;
14405 submerge(true);
14406 solid_update(false);
14407
14408 [[fallthrough]];
14409 default:
14410 if(clk>=(146+zc_max(0,dmisc5)))
14411 clk=-1;
14412
14413 break;
14414 }
14415 }
14416
14417 return enemy::animate(index);
14418 }
14419
14420 void eWizzrobe::wizzrobe_attack_for_real()
14421 {
14422 if(wpn==0) // Edited enemies
14423 return;
14424
14425 if(dmisc2 == 0) //normal weapon
14426 {
14427 addEwpn(x,y,z,wpn,0,wdp,dir,getUID(), 0, fakez);
14428 sfx(WAV_WAND,pan(int32_t(x)));
14429 }
14430 else if(dmisc2 == 1) // ring of fire
14431 {
14432 addEwpn(x,y,z,wpn,0,wdp,up,getUID(), 0, fakez);
14433 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14434 addEwpn(x,y,z,wpn,0,wdp,down,getUID(), 0, fakez);
14435 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14436 addEwpn(x,y,z,wpn,0,wdp,left,getUID(), 0, fakez);
14437 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14438 addEwpn(x,y,z,wpn,0,wdp,right,getUID(), 0, fakez);
14439 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14440 addEwpn(x,y,z,wpn,0,wdp,l_up,getUID(), 0, fakez);
14441 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14442 addEwpn(x,y,z,wpn,0,wdp,r_up,getUID(), 0, fakez);
14443 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14444 addEwpn(x,y,z,wpn,0,wdp,l_down,getUID(), 0, fakez);
14445 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14446 addEwpn(x,y,z,wpn,0,wdp,r_down,getUID(), 0, fakez);
14447 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14448 sfx(WAV_FIRE,pan(int32_t(x)));
14449 if (get_bit(quest_rules, qr_8WAY_SHOT_SFX)) sfx(WAV_FIRE,pan(int32_t(x)));
14450 else
14451 {
14452 switch(wpn)
14453 {
14454 case ewFireball: sfx(40,pan(int32_t(x))); break;
14455
14456 case ewArrow: sfx(1,pan(int32_t(x))); break; //Ghost.zh has 0?
14457 case ewBrang: sfx(4,pan(int32_t(x))); break; //Ghost.zh has 0?
14458 case ewSword: sfx(20,pan(int32_t(x))); break; //Ghost.zh has 0?
14459 case ewRock: sfx(51,pan(int32_t(x))); break;
14460 case ewMagic: sfx(32,pan(int32_t(x))); break;
14461 case ewBomb: sfx(3,pan(int32_t(x))); break; //Ghost.zh has 0?
14462 case ewSBomb: sfx(3,pan(int32_t(x))); break; //Ghost.zh has 0?
14463 case ewLitBomb: sfx(21,pan(int32_t(x))); break; //Ghost.zh has 0?
14464 case ewLitSBomb: sfx(21,pan(int32_t(x))); break; //Ghost.zh has 0?
14465 case ewFireTrail: sfx(13,pan(int32_t(x))); break;
14466 case ewFlame: sfx(13,pan(int32_t(x))); break;
14467 case ewWind: sfx(32,pan(int32_t(x))); break;
14468 case ewFlame2: sfx(13,pan(int32_t(x))); break;
14469 case ewFlame2Trail: sfx(13,pan(int32_t(x))); break;
14470 case ewIce: sfx(44,pan(int32_t(x))); break;
14471 case ewFireball2: sfx(40,pan(int32_t(x))); break; //fireball (rising)
14472 default: sfx(WAV_FIRE,pan(int32_t(x))); break;
14473
14474 }
14475 }
14476 }
14477 else if(dmisc2==2) // summons specific enemy
14478 {
14479 int32_t bc=0;
14480
14481 for(int32_t gc=0; gc<guys.Count(); gc++)
14482 {
14483 if((((enemy*)guys.spr(gc))->id) == dmisc3)
14484 {
14485 ++bc;
14486 }
14487 }
14488
14489 if(bc<=40)
14490 {
14491 int32_t kids = guys.Count();
14492 int32_t bats=(zc_oldrand()%3)+1;
14493
14494 for(int32_t i=0; i<bats; i++)
14495 {
14496 // Summon bats (or anything)
14497 if(addchild(x,y,dmisc3,-10, this->script_UID))
14498 ((enemy*)guys.spr(kids+i))->count_enemy = false;
14499 }
14500
14501 sfx(WAV_FIRE,pan(int32_t(x)));
14502 }
14503 }
14504 else if(dmisc2==3) //summon from layer
14505 {
14506 if(count_layer_enemies()==0)
14507 {
14508 return;
14509 }
14510
14511 int32_t kids = guys.Count();
14512
14513 if(kids<200)
14514 {
14515 int32_t newguys=(zc_oldrand()%3)+1;
14516 bool summoned=false;
14517
14518 for(int32_t i=0; i<newguys; i++)
14519 {
14520 int32_t id2=vbound(random_layer_enemy(),eSTART,eMAXGUYS-1);
14521 int32_t x2=0;
14522 int32_t y2=0;
14523
14524 for(int32_t k=0; k<20; ++k)
14525 {
14526 x2=16*((zc_oldrand()%12)+2);
14527 y2=16*((zc_oldrand()%7)+2);
14528
14529 if(!m_walkflag(x2,y2,0, dir) && (abs(x2-Hero.getX())>=32 || abs(y2-Hero.getY())>=32))
14530 {
14531 if(addchild(x2,y2,get_bit(quest_rules,qr_ENEMIESZAXIS) ? 64 : 0,id2,-10, this->script_UID))
14532 {
14533 ((enemy*)guys.spr(kids+i))->count_enemy = false;
14534 if (get_bit(quest_rules,qr_ENEMIESZAXIS) && (((enemy*)guys.spr(kids+i))->moveflags & FLAG_USE_FAKE_Z))
14535 {
14536 ((enemy*)guys.spr(kids+i))->fakez = 64;
14537 ((enemy*)guys.spr(kids+i))->z = 0;
14538 }
14539 }
14540
14541 summoned=true;
14542 break;
14543 }
14544 }
14545 }
14546
14547 if(summoned)
14548 {
14549 sfx(get_bit(quest_rules,qr_MORESOUNDS) ? WAV_ZN1SUMMON : WAV_FIRE,pan(int32_t(x)));
14550 }
14551 }
14552 }
14553 }
14554
14555
14556 void eWizzrobe::wizzrobe_attack()
14557 {
14558 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
14559 return;
14560
14561 if(clk3<=0 || ((clk3&31)==0 && !canmove(dir,(zfix)1,spw_door,false) && !misc))
14562 {
14563 fix_coords();
14564
14565 switch(misc)
14566 {
14567 case 1: //walking
14568 if(!m_walkflag(x,y,spw_door, dir))
14569 misc=0;
14570 else
14571 {
14572 clk3=16;
14573
14574 if(!canmove(dir,(zfix)1,spw_wizzrobe,false))
14575 {
14576 wizzrobe_newdir(0);
14577 }
14578 }
14579
14580 break;
14581
14582 case 2: //phasing
14583 {
14584 int32_t jx=x;
14585 int32_t jy=y;
14586 int32_t jdir=-1;
14587
14588 switch(zc_oldrand()&7)
14589 {
14590 case 0:
14591 jx-=32;
14592 jy-=32;
14593 jdir=15;
14594 break;
14595
14596 case 1:
14597 jx+=32;
14598 jy-=32;
14599 jdir=9;
14600 break;
14601
14602 case 2:
14603 jx+=32;
14604 jy+=32;
14605 jdir=11;
14606 break;
14607
14608 case 3:
14609 jx-=32;
14610 jy+=32;
14611 jdir=13;
14612 break;
14613 }
14614
14615 if(jdir>0 && jx>=32 && jx<=208 && jy>=32 && jy<=128)
14616 {
14617 misc=3;
14618 clk3=32;
14619 dir=jdir;
14620 break;
14621 }
14622 }
14623 [[fallthrough]];
14624 case 3:
14625 dir&=3;
14626 misc=0;
14627 [[fallthrough]];
14628 case 0:
14629 wizzrobe_newdir(64);
14630 [[fallthrough]];
14631 default:
14632 if(!canmove(dir,(zfix)1,spw_door,false))
14633 {
14634 if(canmove(dir,(zfix)15,spw_wizzrobe,false))
14635 {
14636 misc=1;
14637 clk3=16;
14638 }
14639 else
14640 {
14641 wizzrobe_newdir(64);
14642 misc=0;
14643 clk3=32;
14644 }
14645 }
14646 else
14647 {
14648 clk3=32;
14649 }
14650
14651 break;
14652 }
14653
14654 if(misc<0)
14655 ++misc;
14656 }
14657
14658 --clk3;
14659
14660 switch(misc)
14661 {
14662 case 1:
14663 case 3:
14664 step=1;
14665 break;
14666
14667 case 2:
14668 step=0;
14669 break;
14670
14671 default:
14672 step=0.5;
14673 break;
14674
14675 }
14676
14677 move(step);
14678
14679 // if(d->misc1 && misc<=0 && clk3==28)
14680 if(dmisc1 && misc<=0 && clk3==28)
14681 {
14682 if(dmisc2 != 1)
14683 {
14684 if(lined_up(8,false) == dir)
14685 {
14686 // addEwpn(x,y,z,wpn,0,wdp,dir,getUID());
14687 // sfx(WAV_WAND,pan(int32_t(x)));
14688 wizzrobe_attack_for_real();
14689 fclk=30;
14690 }
14691 }
14692 else
14693 {
14694 if((zc_oldrand()%500)>=400)
14695 {
14696 wizzrobe_attack_for_real();
14697 fclk=30;
14698 }
14699 }
14700 }
14701
14702 if(misc==0 && (zc_oldrand()&127)==0)
14703 misc=2;
14704
14705 if(misc==2 && clk3==4)
14706 fix_coords();
14707
14708 if(!(charging||firing)) //should never be charging or firing for these wizzrobes
14709 {
14710 if(fclk>0)
14711 {
14712 --fclk;
14713 }
14714 }
14715
14716 }
14717
14718 void eWizzrobe::wizzrobe_newdir(int32_t homing)
14719 {
14720 // Wizzrobes shouldn't move to the edge of the screen;
14721 // if they're already there, they should move toward the center
14722 if(x<32)
14723 dir=right;
14724 else if(x>=224)
14725 dir=left;
14726 else if(y<32)
14727 dir=down;
14728 else if(y>=144)
14729 dir=up;
14730 else
14731 newdir(4,homing,spw_wizzrobe);
14732 }
14733
14734 void eWizzrobe::draw(BITMAP *dest)
14735 {
14736 // if(d->misc1 && (misc==1 || misc==3) && (clk3&1) && hp>0 && !watch && !stunclk) // phasing
14737 if(dmisc1 && (misc==1 || misc==3) && (clk3&1) && hp>0 && !watch && !stunclk && !frozenclock) // phasing
14738 return;
14739
14740 int32_t tempint=dummy_int[1];
14741 bool tempbool1=dummy_bool[1];
14742 bool tempbool2=dummy_bool[2];
14743 dummy_int[1]=fclk;
14744 dummy_bool[1]=charging;
14745 dummy_bool[2]=firing;
14746 update_enemy_frame();
14747 dummy_int[1]=tempint;
14748 dummy_bool[1]=tempbool1;
14749 dummy_bool[2]=tempbool2;
14750 enemy::draw(dest);
14751 }
14752
14753 /*********************************/
14754 /********** Bosses ***********/
14755 /*********************************/
14756
14757 eDodongo::eDodongo(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
14758 {
14759 fading=fade_flash_die;
14760 //nets+5120;
14761 if(dir==down&&y>=128)
14762 {
14763 dir=up;
14764 }
14765
14766 if(dir==right&&x>=208)
14767 {
14768 dir=left;
14769 }
14770 SIZEflags = d->SIZEflags;
14771 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
14772 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
14773 // al_trace("Enemy txsz:%i\n", txsz);
14774 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
14775 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
14776 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
14777 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
14778 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
14779 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
14780 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
14781 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
14782 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
14783 {
14784 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
14785 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
14786 }
14787
14788 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
14789 }
14790
14791 bool eDodongo::animate(int32_t index)
14792 {
14793 if(switch_hooked) return enemy::animate(index);
14794 if(dying)
14795 {
14796 return Dead(index);
14797 }
14798
14799 if(clk==0)
14800 {
14801 removearmos(x,y,ffcactivated);
14802 }
14803
14804 if(clk2) // ate a bomb
14805 {
14806 if(--clk2==0)
14807 hp-=misc; // store bomb's power in misc
14808 }
14809 else
14810 constant_walk(rate,homing,spw_clipright);
14811
14812 hxsz = (dir<=down) ? 16 : 32;
14813 // hysz = (dir>=left) ? 16 : 32;
14814
14815 return enemy::animate(index);
14816 }
14817
14818 void eDodongo::draw(BITMAP *dest)
14819 {
14820 tile=o_tile;
14821
14822 if(clk<0)
14823 {
14824 enemy::drawzcboss(dest);
14825 return;
14826 }
14827
14828 update_enemy_frame();
14829 enemy::drawzcboss(dest);
14830
14831 if(dummy_int[1]!=0) //additional tiles
14832 {
14833 tile+=dummy_int[1]; //second tile is previous tile
14834 xofs-=16; //new xofs change
14835 enemy::drawzcboss(dest);
14836 xofs+=16;
14837 }
14838
14839 }
14840
14841 int32_t eDodongo::takehit(weapon *w)
14842 {
14843 int32_t wpnId = w->id;
14844 int32_t power = w->power;
14845 int32_t wpnx = w->x;
14846 int32_t wpny = w->y;
14847
14848 if(dying || clk<0 || clk2>0 || (superman && !(superman>1 && wpnId==wSBomb)))
14849 return 0;
14850
14851 switch(wpnId)
14852 {
14853 case wPhantom:
14854 return 0;
14855
14856 case wFire:
14857 case wBait:
14858 case wWhistle:
14859 case wWind:
14860 case wSSparkle:
14861 case wFSparkle:
14862 return 0;
14863
14864 case wLitBomb:
14865 case wLitSBomb:
14866 if(abs(wpnx-((dir==right)?x+16:x)) > 7 || abs(wpny-y) > 7)
14867 return 0;
14868
14869 clk2=96;
14870 misc=power;
14871
14872 if(wpnId==wLitSBomb)
14873 item_set=isSBOMB100;
14874
14875 return 1;
14876
14877 case wBomb:
14878 case wSBomb:
14879 if(abs(wpnx-((dir==right)?x+16:x)) > 8 || abs(wpny-y) > 8)
14880 return 0;
14881
14882 stunclk=160;
14883 misc=wpnId; // store wpnId
14884 return 1;
14885
14886 case wSword:
14887 if(stunclk)
14888 {
14889 sfx(WAV_EHIT,pan(int32_t(x)));
14890 hp=0;
14891 item_set = (misc==wSBomb) ? isSBOMB100 : isBOMB100;
14892 fading=0; // don't flash
14893 return 1;
14894 }
14895
14896 [[fallthrough]];
14897 default:
14898 sfx(WAV_CHINK,pan(int32_t(x)));
14899 }
14900
14901 return 1;
14902 }
14903
14904 eDodongo2::eDodongo2(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
14905 {
14906 fading=fade_flash_die;
14907 //nets+5180;
14908 previous_dir=-1;
14909 if(dir==down&&y>=128)
14910 {
14911 dir=up;
14912 }
14913
14914 if(dir==right&&x>=208)
14915 {
14916 dir=left;
14917 }
14918 SIZEflags = d->SIZEflags;
14919 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
14920 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
14921 // al_trace("Enemy txsz:%i\n", txsz);
14922 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
14923 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
14924 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
14925 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
14926 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
14927 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
14928 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
14929 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
14930 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
14931 {
14932 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
14933 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
14934 }
14935
14936 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
14937 }
14938
14939 bool eDodongo2::animate(int32_t index)
14940 {
14941 if(switch_hooked) return enemy::animate(index);
14942 if(dying)
14943 {
14944 return Dead(index);
14945 }
14946
14947 if(clk==0)
14948 {
14949 removearmos(x,y,ffcactivated);
14950 }
14951
14952 if(clk2) // ate a bomb
14953 {
14954 if(--clk2==0)
14955 hp-=misc; // store bomb's power in misc
14956 }
14957 else
14958 constant_walk(rate,homing,spw_clipbottomright);
14959
14960 hxsz = (dir<=down) ? 16 : 32;
14961 hysz = (dir>=left) ? 16 : 32;
14962 hxofs=(dir>=left)?-8:0;
14963 hyofs=(dir<left)?-8:0;
14964
14965 return enemy::animate(index);
14966 }
14967
14968 void eDodongo2::draw(BITMAP *dest)
14969 {
14970 if(clk<0)
14971 {
14972 enemy::drawzcboss(dest);
14973 return;
14974 }
14975
14976 int32_t tempx=xofs;
14977 int32_t tempy=yofs;
14978 update_enemy_frame();
14979 enemy::drawzcboss(dest);
14980 tile+=dummy_int[1]; //second tile change
14981 xofs+=dummy_int[2]; //new xofs change
14982 yofs+=dummy_int[3]; //new yofs change
14983 enemy::drawzcboss(dest);
14984 xofs=tempx;
14985 yofs=tempy;
14986 }
14987
14988 int32_t eDodongo2::takehit(weapon *w)
14989 {
14990 int32_t wpnId = w->id;
14991 int32_t power = w->power;
14992 int32_t wpnx = w->x;
14993 int32_t wpny = w->y;
14994
14995 if(dying || clk<0 || clk2>0 || superman)
14996 return 0;
14997
14998 switch(wpnId)
14999 {
15000 case wPhantom:
15001 return 0;
15002
15003 case wFire:
15004 case wBait:
15005 case wWhistle:
15006 case wWind:
15007 case wSSparkle:
15008 case wFSparkle:
15009 return 0;
15010
15011 case wLitBomb:
15012 case wLitSBomb:
15013 switch(dir)
15014 {
15015 case up:
15016 if(abs(wpnx-x) > 7 || abs(wpny-(y-8)) > 7)
15017 return 0;
15018
15019 break;
15020
15021 case down:
15022 if(abs(wpnx-x) > 7 || abs(wpny-(y+8)) > 7)
15023 return 0;
15024
15025 break;
15026
15027 case left:
15028 if(abs(wpnx-(x-8)) > 7 || abs(wpny-y) > 7)
15029 return 0;
15030
15031 break;
15032
15033 case right:
15034 if(abs(wpnx-(x+8)) > 7 || abs(wpny-y) > 7)
15035 return 0;
15036
15037 break;
15038 }
15039
15040 // if(abs(wpnx-((dir==right)?x+8:(dir==left)?x-8:0)) > 7 || abs(wpny-((dir==down)?y+8:(dir==up)?y-8:0)) > 7)
15041 // return 0;
15042 clk2=96;
15043 misc=power;
15044
15045 if(wpnId==wLitSBomb)
15046 item_set=isSBOMB100;
15047
15048 return 1;
15049
15050 case wBomb:
15051 case wSBomb:
15052 switch(dir)
15053 {
15054 case up:
15055 if(abs(wpnx-x) > 7 || abs(wpny-(y-8)) > 7)
15056 return 0;
15057
15058 break;
15059
15060 case down:
15061 if(abs(wpnx-x) > 7 || abs(wpny-(y+8)) > 7)
15062 return 0;
15063
15064 break;
15065
15066 case left:
15067 if(abs(wpnx-(x-8)) > 7 || abs(wpny-y) > 7)
15068 return 0;
15069
15070 break;
15071
15072 case right:
15073 if(abs(wpnx-(x+8)) > 7 || abs(wpny-y) > 7)
15074 return 0;
15075
15076 break;
15077 }
15078
15079 stunclk=160;
15080 misc=wpnId; // store wpnId
15081 return 1;
15082
15083 case wSword:
15084 if(stunclk)
15085 {
15086 sfx(WAV_EHIT,pan(int32_t(x)));
15087 hp=0;
15088 item_set = (misc==wSBomb) ? isSBOMB100 : isBOMB100;
15089 fading=0; // don't flash
15090 return 1;
15091 }
15092
15093 [[fallthrough]];
15094 default:
15095 sfx(WAV_CHINK,pan(int32_t(x)));
15096 }
15097
15098 return 1;
15099 }
15100
15101 3 eAquamentus::eAquamentus(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)//enemy((zfix)176,(zfix)64,Id,Clk)
15102 3 {
15103 //these are here to bypass compiler warnings about unused arguments
15104
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if ( !(editorflags & ENEMY_FLAG5) )
15105 {
15106
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 x = dmisc1 ? 64 : 176;
15107
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 y = 64;
15108 1 }
15109 else { x = X; y = Y; }
15110
15111 //nets+5940;
15112
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if(get_bit(quest_rules,qr_NEWENEMYTILES))
15113 {
15114 }
15115 else
15116 {
15117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(dmisc1)
15118 {
15119 flip=1;
15120 }
15121 }
15122
15123
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset)+1;
15124 1 clk3=32;
15125 1 clk2=0;
15126 1 clk4=clk;
15127 1 dir=left;
15128 1 SIZEflags = d->SIZEflags;
15129
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
15130 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
15131 // al_trace("Enemy txsz:%i\n", txsz);
15132
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
15133
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
15134
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
15135
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
15136
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
15137
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
15138 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
15139
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
15140
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
15141 {
15142 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
15143 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
15144 }
15145
15146
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
15147 2 }
15148
15149 687 bool eAquamentus::animate(int32_t index)
15150 {
15151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 687 times.
687 if(switch_hooked) return enemy::animate(index);
15152
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 669 times.
687 if(dying)
15153 18 return Dead(index);
15154
15155 // fbx=x+((id==eRAQUAM)?4:-4);
15156
2/2
✓ Branch 0 taken 666 times.
✓ Branch 1 taken 3 times.
669 if(clk==0)
15157 {
15158 3 removearmos(x,y,ffcactivated);
15159 3 }
15160
15161 669 fbx=x;
15162
15163 /*
15164 if (get_bit(quest_rules,qr_NEWENEMYTILES)&&id==eLAQUAM)
15165 {
15166 fbx+=16;
15167 }
15168 */
15169
2/2
✓ Branch 0 taken 664 times.
✓ Branch 1 taken 5 times.
669 if(--clk3==0)
15170 {
15171 // addEwpn(fbx,y,z,ewFireball,0,d->wdp,up+1);
15172 // addEwpn(fbx,y,z,ewFireball,0,d->wdp,0);
15173 // addEwpn(fbx,y,z,ewFireball,0,d->wdp,down+1);
15174 5 addEwpn(fbx,y,z,wpn,2,wdp,up,getUID(), 0, fakez);
15175 5 addEwpn(fbx,y,z,wpn,2,wdp,8,getUID(), 0, fakez);
15176 5 addEwpn(fbx,y,z,wpn,2,wdp,down,getUID(), 0, fakez);
15177 5 sfx(wpnsfx(wpn),pan(int32_t(x)));
15178 5 }
15179
15180
4/4
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 549 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 116 times.
669 if(clk3<-80 && !(zc_oldrand()&63))
15181 {
15182 4 clk3=32;
15183 4 }
15184
15185
2/2
✓ Branch 0 taken 658 times.
✓ Branch 1 taken 11 times.
669 if(!((clk4+1)&63))
15186 {
15187 11 int32_t d2=(zc_oldrand()%3)+1;
15188
15189
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 8 times.
11 if(d2>=left)
15190 {
15191 8 dir=d2;
15192 8 }
15193
15194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if(dmisc1)
15195 {
15196 if(x<=40)
15197 {
15198 dir=right;
15199 }
15200
15201 if(x>=104)
15202 {
15203 dir=left;
15204 }
15205 }
15206 else
15207 {
15208
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(x<=136)
15209 {
15210 dir=right;
15211 }
15212
15213
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(x>=200)
15214 {
15215 dir=left;
15216 }
15217 }
15218 11 }
15219
15220
4/4
✓ Branch 0 taken 655 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 573 times.
✓ Branch 3 taken 82 times.
669 if(clk4>=-1 && !((clk4+1)&7))
15221 {
15222
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 32 times.
82 if(dir==left)
15223 {
15224 50 x-=1;
15225 50 }
15226 else
15227 {
15228 32 x+=1;
15229 }
15230 82 }
15231
15232 669 clk4=(clk4+1)%256;
15233
15234 669 return enemy::animate(index);
15235 687 }
15236
15237 687 void eAquamentus::draw(BITMAP *dest)
15238 {
15239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 687 times.
687 if(get_bit(quest_rules,qr_NEWENEMYTILES))
15240 {
15241 xofs=(dmisc1?-16:0);
15242 if ( do_animation ) tile=o_tile+((clk&24)>>2)+(clk3>-32?(clk3>0?40:80):0);
15243
15244 if(dying)
15245 {
15246 xofs=0;
15247 enemy::draw(dest);
15248 }
15249 else
15250 {
15251 drawblock(dest,15);
15252 }
15253 }
15254 else
15255 {
15256 687 int32_t xblockofs=((dmisc1)?-16:16);
15257 687 xofs=0;
15258
15259
4/4
✓ Branch 0 taken 672 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 654 times.
687 if(clk<0 || dying)
15260 {
15261 33 enemy::draw(dest);
15262 33 return;
15263 }
15264
1/2
✓ Branch 0 taken 654 times.
✗ Branch 1 not taken.
654 if ( do_animation )
15265 {
15266 // face (0=firing, 2=resting)
15267 654 tile=o_tile+((clk3>0)?0:2);
15268 654 enemy::draw(dest);
15269 // tail (
15270 654 tile=o_tile+((clk&16)?1:3);
15271 654 xofs=xblockofs;
15272 654 enemy::draw(dest);
15273 // body
15274 654 yofs+=16;
15275 654 xofs=0;
15276 654 tile=o_tile+((clk&16)?20:22);
15277 654 enemy::draw(dest);
15278 654 xofs=xblockofs;
15279 654 tile=o_tile+((clk&16)?21:23);
15280 654 enemy::draw(dest);
15281 654 yofs-=16;
15282 654 }
15283 else enemy::draw(dest);
15284 }
15285 687 }
15286
15287 183 bool eAquamentus::hit(weapon *w)
15288 {
15289
3/6
✓ Branch 0 taken 183 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 183 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 183 times.
183 if(!(w->scriptcoldet&1) || w->fallclk || w->drownclk) return false;
15290
15291
1/2
✓ Branch 0 taken 183 times.
✗ Branch 1 not taken.
183 switch(w->id)
15292 {
15293 case wBeam:
15294 case wRefBeam:
15295 case wMagic:
15296 183 hysz=32;
15297 183 }
15298
15299
2/4
✓ Branch 0 taken 183 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 183 times.
✗ Branch 3 not taken.
183 bool ret = (dying || hclk>0) ? false : sprite::hit(w);
15300 183 hysz=16;
15301 183 return ret;
15302
15303 183 }
15304
15305 eGohma::eGohma(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk) // enemy((zfix)128,(zfix)48,Id,0)
15306 {
15307
15308 if ( !(editorflags & ENEMY_FLAG5) )
15309 {
15310 x = 128;
15311 y = 48;
15312 }
15313 else { x = X; y = Y; }
15314
15315 Clk=Clk;
15316 if(flags & guy_fadeflicker)
15317 {
15318 clk=0;
15319 superman = 1;
15320 fading=fade_flicker;
15321 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
15322 }
15323 else if(flags & guy_fadeinstant)
15324 {
15325 clk=0;
15326 }
15327 hxofs=-16;
15328 hxsz=48;
15329 clk4=0;
15330 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset)+1;
15331 dir=zc_oldrand()%3+1;
15332 SIZEflags = d->SIZEflags;
15333 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
15334 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
15335 // al_trace("Enemy txsz:%i\n", txsz);
15336 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = tysz; if ( tysz > 1 ) extend = 3; }
15337 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = hxsz;
15338 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = hysz;
15339 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = hzsz;
15340 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = hxofs;
15341 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = hyofs;
15342 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
15343 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)xofs;
15344 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
15345 {
15346 yofs = (int32_t)yofs; //This seems to be setting to +48 or something with any value set?! -Z
15347 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
15348 }
15349
15350 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
15351
15352 //nets+5340;
15353 }
15354
15355 bool eGohma::animate(int32_t index)
15356 {
15357 if(switch_hooked) return enemy::animate(index);
15358 if(dying)
15359 return Dead(index);
15360
15361 if(fading)
15362 {
15363 if(++clk4 > 60)
15364 {
15365 clk4=0;
15366 superman=0;
15367 fading=0;
15368 clk=0;
15369
15370 }
15371 else return enemy::animate(index);
15372 }
15373
15374 if(clk==0)
15375 {
15376 if (ffcactivated) removearmosffc(ffcactivated-1);
15377 else
15378 {
15379 removearmos(zc_max(x-16, zfix(0)),y);
15380 did_armos = false;
15381 removearmos(x,y);
15382 did_armos = false;
15383 removearmos(zc_min(x+16, zfix(255)),y);
15384 }
15385 }
15386
15387 if(clk<0) return enemy::animate(index);
15388
15389 // Movement clk must be separate from animation clk because of the Clock item
15390 if(!watch)
15391 clk4++;
15392
15393 if((clk4&63)==0)
15394 {
15395 if(clk4&64)
15396 dir^=1;
15397 else
15398 dir=zc_oldrand()%3+1;
15399 }
15400
15401 if((clk&63)==3)
15402 {
15403 switch(dmisc1)
15404 {
15405 case 1:
15406 addEwpn(x,y+2,z,wpn,3,wdp,left,getUID(), 0, fakez);
15407 addEwpn(x,y+2,z,wpn,3,wdp,8,getUID(), 0, fakez);
15408 addEwpn(x,y+2,z,wpn,3,wdp,right,getUID(), 0, fakez);
15409 sfx(wpnsfx(wpn),pan(int32_t(x)));
15410 break;
15411
15412 default:
15413 if(dmisc1 != 1 && dmisc1 != 2)
15414 {
15415 addEwpn(x,y+2,z,wpn,3,wdp,8,getUID(), 0, fakez);
15416 sfx(wpnsfx(wpn),pan(int32_t(x)));
15417 sfx(wpnsfx(wpn),pan(int32_t(x)));
15418 }
15419
15420 break;
15421 }
15422 }
15423
15424 if((dmisc1 == 2)&& clk3>=16 && clk3<116)
15425 {
15426 if(!(clk3%8))
15427 {
15428 FireBreath(true);
15429 }
15430 }
15431
15432 if(clk4&1)
15433 move((zfix)1);
15434
15435 if(++clk3>=400)
15436 clk3=0;
15437
15438 return enemy::animate(index);
15439 }
15440
15441 void eGohma::draw(BITMAP *dest)
15442 {
15443 tile=o_tile;
15444
15445 if(clk<0 || dying)
15446 {
15447 enemy::drawzcboss(dest);
15448 return;
15449 }
15450
15451 if(get_bit(quest_rules,qr_NEWENEMYTILES))
15452 {
15453 ///if ( do_animation )
15454 //Yuck. Gohma can just not have this capability right now.
15455 // left side
15456 xofs=-16;
15457 flip=0;
15458 // if(clk&16) tile=180;
15459 // else { tile=182; flip=1; }
15460 tile+=(3*((clk&48)>>4));
15461 enemy::drawzcboss(dest);
15462
15463 // right side
15464 xofs=16;
15465 // tile=(180+182)-tile;
15466 tile=o_tile;
15467 tile+=(3*((clk&48)>>4))+2;
15468 enemy::drawzcboss(dest);
15469
15470 // body
15471 xofs=0; //Gohma may need more adjustments for SIZEflags. -Z 14 Aug 2020
15472 tile=o_tile;
15473
15474 // tile+=(3*((clk&24)>>3))+2;
15475 if(clk3<16)
15476 tile+=7;
15477 else if(clk3<116)
15478 tile+=10;
15479 else if(clk3<132)
15480 tile+=7;
15481 else
15482 tile+=((clk3-132)&24)?4:1;
15483
15484 enemy::drawzcboss(dest);
15485
15486 }
15487 else
15488 {
15489 // left side
15490 xofs=-16;
15491 flip=0;
15492
15493 if(!(clk&16))
15494 {
15495 tile+=2;
15496 flip=1;
15497 }
15498
15499 enemy::draw(dest);
15500
15501 // right side
15502 tile=o_tile;
15503 xofs=16;
15504
15505 if((clk&16)) tile+=2;
15506
15507 // tile=(180+182)-tile;
15508 enemy::draw(dest);
15509
15510 // body
15511 tile=o_tile;
15512 xofs=0;
15513
15514 if(clk3<16)
15515 tile+=4;
15516 else if(clk3<116)
15517 tile+=5;
15518 else if(clk3<132)
15519 tile+=4;
15520 else tile+=((clk3-132)&8)?3:1;
15521
15522 enemy::draw(dest);
15523
15524 }
15525 }
15526
15527 int32_t eGohma::takehit(weapon *w)
15528 {
15529 int32_t wpnId = w->id;
15530 int32_t power = w->power;
15531 int32_t wpnx = w->x;
15532 int32_t wpnDir = w->dir;
15533 int32_t def = defenditemclassNew(wpnId, &power, w);
15534
15535 if(def < 0)
15536 {
15537 if(!((wpnDir==up || wpnDir==l_up || wpnDir==r_up) && abs(int32_t(x)-wpnx)<=8 && clk3>=16 && clk3<116))
15538 {
15539 sfx(WAV_CHINK,pan(int32_t(x)));
15540 return 1;
15541 }
15542 }
15543
15544 return enemy::takehit(w);
15545 }
15546
15547 eLilDig::eLilDig(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
15548 {
15549 count_enemy=(id==(id&0xFFF));
15550 //nets+4360+(((id&0xFF)-eDIGPUP2)*40);
15551 SIZEflags = d->SIZEflags;
15552 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
15553 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
15554 // al_trace("Enemy txsz:%i\n", txsz);
15555 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
15556 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
15557 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
15558 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
15559 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
15560 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
15561 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
15562 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
15563 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
15564 {
15565 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
15566 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
15567 }
15568
15569 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
15570 }
15571
15572 bool eLilDig::animate(int32_t index)
15573 {
15574 if(switch_hooked) return enemy::animate(index);
15575 if(dying)
15576 return Dead(index);
15577
15578 if(clk==0)
15579 {
15580 removearmos(x,y,ffcactivated);
15581 }
15582
15583 if(misc<=128)
15584 {
15585 if(!(++misc&31))
15586 step+=0.25;
15587 }
15588
15589 variable_walk_8(rate,homing,hrate,spw_floater);
15590 return enemy::animate(index);
15591 }
15592
15593 void eLilDig::draw(BITMAP *dest)
15594 {
15595 tile = o_tile;
15596 // tile = 160;
15597 int32_t fdiv = frate/4;
15598 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
15599 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
15600 efrate:((clk>=(frate>>1))?1:0);
15601
15602 if ( do_animation )
15603 {
15604 if(get_bit(quest_rules,qr_NEWENEMYTILES))
15605 {
15606 switch(dir-8) //directions get screwed up after 8. *shrug*
15607 {
15608 case up: //u
15609 flip=0;
15610 break;
15611
15612 case l_up: //d
15613 flip=0;
15614 tile+=4;
15615 break;
15616
15617 case l_down: //l
15618 flip=0;
15619 tile+=8;
15620 break;
15621
15622 case left: //r
15623 flip=0;
15624 tile+=12;
15625 break;
15626
15627 case r_down: //ul
15628 flip=0;
15629 tile+=20;
15630 break;
15631
15632 case down: //ur
15633 flip=0;
15634 tile+=24;
15635 break;
15636
15637 case r_up: //dl
15638 flip=0;
15639 tile+=28;
15640 break;
15641
15642 case right: //dr
15643 flip=0;
15644 tile+=32;
15645 break;
15646 }
15647
15648 tile+=f2;
15649 }
15650 else
15651 {
15652 tile+=(clk>=6)?1:0;
15653 }
15654 }
15655
15656 enemy::draw(dest);
15657 }
15658
15659 eBigDig::eBigDig(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
15660 {
15661 superman=1;
15662
15663 SIZEflags = d->SIZEflags;
15664 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
15665 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
15666 // al_trace("Enemy txsz:%i\n", txsz);
15667 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
15668 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
15669 else hxsz=32;
15670 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
15671 else hysz=32;
15672 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
15673 else hzsz=16; // hard to jump.
15674 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
15675 else hxofs=-8;
15676 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
15677 else hyofs=-8;
15678 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
15679 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
15680 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
15681 {
15682 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
15683 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
15684 }
15685
15686 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
15687
15688
15689 }
15690
15691 bool eBigDig::animate(int32_t index)
15692 {
15693 if(switch_hooked) return enemy::animate(index);
15694 if(dying)
15695 return Dead(index);
15696
15697 if(clk==0)
15698 {
15699 removearmos(x,y,ffcactivated);
15700 }
15701
15702 switch(misc)
15703 {
15704 case 0:
15705 variable_walk_8(rate,homing,hrate,spw_floater,-8,-16,23,23);
15706 break;
15707
15708 case 1:
15709 ++misc;
15710 break;
15711
15712 case 2:
15713 for(int32_t i=0; i<dmisc5; i++)
15714 {
15715 addenemy(x,y,dmisc1+0x1000,-15);
15716 }
15717
15718 for(int32_t i=0; i<dmisc6; i++)
15719 {
15720 addenemy(x,y,dmisc2+0x1000,-15);
15721 }
15722
15723 for(int32_t i=0; i<dmisc7; i++)
15724 {
15725 addenemy(x,y,dmisc3+0x1000,-15);
15726 }
15727
15728 for(int32_t i=0; i<dmisc8; i++)
15729 {
15730 addenemy(x,y,dmisc4+0x1000,-15);
15731 }
15732
15733 if(itemguy) // Hand down the carried item
15734 {
15735 guycarryingitem = guys.Count()-1;
15736 ((enemy*)guys.spr(guycarryingitem))->itemguy = true;
15737 itemguy = false;
15738 }
15739
15740 stop_bgsfx(index);
15741
15742 if(deadsfx > 0) sfx(deadsfx,pan(int32_t(x)));
15743
15744 return true;
15745 }
15746
15747 return enemy::animate(index);
15748 }
15749
15750 void eBigDig::draw(BITMAP *dest)
15751 {
15752 if(anim!=aDIG)
15753 {
15754 update_enemy_frame();
15755 xofs-=8;
15756 yofs-=8;
15757 drawblock(dest,15);
15758 xofs+=8;
15759 yofs+=8;
15760 return;
15761 }
15762
15763 tile = o_tile;
15764 int32_t fdiv = frate/4;
15765 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
15766
15767 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
15768 efrate:((clk>=(frate>>1))?1:0);
15769
15770 if ( do_animation )
15771 {
15772 if(get_bit(quest_rules,qr_NEWENEMYTILES))
15773 {
15774 switch(dir-8) //directions get screwed up after 8. *shrug*
15775 {
15776 case up: //u
15777 flip=0;
15778 break;
15779
15780 case l_up: //d
15781 flip=0;
15782 tile+=8;
15783 break;
15784
15785 case l_down: //l
15786 flip=0;
15787 tile+=40;
15788 break;
15789
15790 case left: //r
15791 flip=0;
15792 tile+=48;
15793 break;
15794
15795 case r_down: //ul
15796 flip=0;
15797 tile+=80;
15798 break;
15799
15800 case down: //ur
15801 flip=0;
15802 tile+=88;
15803
15804 break;
15805
15806 case r_up: //dl
15807 flip=0;
15808 tile+=120;
15809 break;
15810
15811 case right: //dr
15812 flip=0;
15813 tile+=128;
15814 break;
15815 }
15816
15817 tile+=(f2*2);
15818 }
15819 else
15820 {
15821 tile+=(f2)?0:2;
15822 flip=(clk&1)?1:0;
15823 }
15824 }
15825
15826 xofs-=8;
15827 yofs-=8;
15828 drawblock(dest,15);
15829 xofs+=8;
15830 yofs+=8;
15831 }
15832
15833 int32_t eBigDig::takehit(weapon *w)
15834 {
15835 int32_t wpnId = w->id;
15836
15837 if(wpnId==wWhistle && misc==0)
15838 misc=1;
15839
15840 return 0;
15841 }
15842
15843 /*
15844 eGanon::eGanon(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
15845 {
15846 hxofs=hyofs=8;
15847 hzsz=16; //can't be jumped.
15848 clk2=70;
15849 misc=-1;
15850 mainguy=!getmapflag();
15851 }
15852
15853 bool eGanon::animate(int32_t index)
15854 {
15855 if(switch_hooked) return enemy::animate(index);
15856 if(dying)
15857
15858 return Dead(index);
15859
15860 if(clk==0)
15861 {
15862 removearmos(x,y,ffcactivated);
15863 }
15864
15865 switch(misc)
15866 {
15867 case -1:
15868 misc=0;
15869
15870 case 0:
15871 if(++clk2>72 && !(zc_oldrand()&3))
15872 {
15873 addEwpn(x,y,z,wpn,3,wdp,dir,getUID());
15874 sfx(wpnsfx(wpn),pan(int32_t(x)));
15875 clk2=0;
15876 }
15877
15878 Stunclk=0;
15879 constant_walk(rate,homing,spw_none);
15880 break;
15881
15882 case 1:
15883 case 2:
15884 if(--Stunclk<=0)
15885 {
15886 int32_t r=zc_oldrand();
15887
15888 if(r&1)
15889 {
15890 y=96;
15891
15892 if(r&2)
15893 x=160;
15894 else
15895 x=48;
15896
15897 if(tooclose(x,y,48))
15898 x=208-x;
15899 }
15900
15901 //if ( editorflags & ENEMY_FLAG15 && current_item_id(itype_amulet,false) >= 2 ) //visible to Amulet 2
15902 //{
15903 // loadpalset(9,pSprite(spBROWN)); //make Ganon visible?
15904 // }
15905 // else
15906 // {
15907 loadpalset(csBOSS,pSprite(d->bosspal));
15908 // }
15909 misc=0;
15910 }
15911
15912 break;
15913
15914 case 3:
15915 {
15916 if(hclk>0)
15917 break;
15918
15919 misc=4;
15920 clk=0;
15921 hxofs=1000;
15922 loadpalset(9,pSprite(spPILE));
15923 music_stop();
15924 stop_sfx(WAV_ROAR);
15925
15926 if(deadsfx>0) sfx(deadsfx,pan(int32_t(x)));
15927
15928 sfx(WAV_GANON);
15929 //Ganon's dustpile; fall in sideview. -Z
15930 item *dustpile = new item(x+8,y+8,(zfix)0,iPile,ipDUMMY,0);
15931 dustpile->linked_parent = eeGANON;
15932 setmapflag();
15933 //items.add(new item(x+8,y+8,(zfix)0,iPile,ipDUMMY,0));
15934 break;
15935 }
15936
15937 case 4:
15938 if(clk>=80)
15939 {
15940 misc=5;
15941
15942 if(getmapflag())
15943 {
15944 game->lvlitems[dlevel]|=liBOSS;
15945 //play_DmapMusic();
15946 playLevelMusic();
15947 return true;
15948 }
15949
15950 sfx(WAV_CLEARED);
15951 items.add(new item(x+8,y+8,(zfix)0,iBigTri,ipBIGTRI,0));
15952 setmapflag();
15953 }
15954
15955 break;
15956 }
15957
15958 //if ( editorflags & ENEMY_FLAG15 ) //visible to Amulet 2
15959 //{
15960 //if ( current_item_id(itype_amulet,false) >= 2 )
15961 //{
15962 /// loadpalset(9,pSprite(spBROWN)); //make Ganon visible?
15963 //}
15964 //}
15965
15966
15967 return enemy::animate(index);
15968 }
15969
15970
15971 int32_t eGanon::takehit(weapon *w)
15972 {
15973 //these are here to bypass compiler warnings about unused arguments
15974 int32_t wpnId = w->id;
15975 int32_t power = w->power;
15976 int32_t enemyHitWeapon = w->parentitem;
15977
15978 switch(misc)
15979 {
15980 case 0:
15981 {
15982 //if we're not using the editor defences, and Ganon isn't hit by a sword, return.
15983 if(wpnId!=wSword && !(editorflags & ENEMY_FLAG14))
15984 return 0;
15985
15986 //if we are not using the new defences, just reduce his HP
15987 if (!(editorflags & ENEMY_FLAG14))
15988 {
15989 hp-=power;
15990 if(hp>0)
15991 {
15992 misc=1;
15993 Stunclk=64;
15994 }
15995 else
15996 {
15997 loadpalset(csBOSS,pSprite(spBROWN));
15998 misc=2;
15999 Stunclk=284;
16000 hp=guysbuf[id&0xFFF].hp; //16*game->get_hero_dmgmult();
16001 }
16002
16003 sfx(WAV_EHIT,pan(int32_t(x)));
16004
16005 if(hitsfx>0) sfx(hitsfx,pan(int32_t(x)));
16006
16007 return 1;
16008 }
16009 //otherwise, resolve his defence.
16010 else
16011 {
16012 int32_t def = enemy::takehit(w); //This works, but it instantly kills him if it does enough damage.
16013 if(hp>0)
16014 {
16015 misc=1;
16016 Stunclk=64;
16017 }
16018 else
16019 {
16020 loadpalset(csBOSS,pSprite(spBROWN));
16021 misc=2;
16022 Stunclk=284;
16023 hp=guysbuf[id&0xFFF].hp; //16*game->get_hero_dmgmult();
16024 }
16025
16026 sfx(WAV_EHIT,pan(int32_t(x)));
16027
16028 if(hitsfx>0) sfx(hitsfx,pan(int32_t(x)));
16029
16030
16031 return 1;
16032 }
16033 }
16034 case 2:
16035 {
16036 if
16037 (
16038 ( dmisc14 > 0 && !enemyHitWeapon == dmisc14 ) //special weapon needed to kill ganon specified in editor
16039 || //or nothing specified, use silver arrows+
16040 ( dmisc14 <= 0 && (wpnId!=wArrow || (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_arrow))<4))
16041 )
16042 return 0;
16043 {
16044 misc=3;
16045 hclk=81;
16046 loadpalset(9,pSprite(spBROWN));
16047 return 1;
16048 }
16049
16050 }
16051 }
16052
16053 return 0;
16054 }
16055
16056 void eGanon::draw(BITMAP *dest)
16057 {
16058 switch(misc)
16059 {
16060 case 0:
16061 if((clk&3)==3)
16062 tile=(zc_oldrand()%5)*2+o_tile;
16063
16064 if(db!=999)
16065 break;
16066
16067 case 2:
16068 if(Stunclk<64 && (Stunclk&1) )
16069 {
16070 if
16071 (
16072 ( (editorflags & ENEMY_FLAG1) && current_item_power(itype_amulet) >= 2 && (editorflags & ENEMY_FLAG15) )
16073 ||
16074 ( (editorflags & ENEMY_FLAG2) && (game->item[dmisc13]) && (editorflags & ENEMY_FLAG15) )
16075 )
16076 {
16077 goto ganon_draw; //draw his weapons if we can see him
16078 }
16079 break;
16080 }
16081
16082 case -1:
16083 tile=o_tile;
16084
16085 //fall through
16086 case 1:
16087 case 3:
16088 ganon_draw:
16089 drawblock(dest,15);
16090 break;
16091
16092 case 4:
16093 draw_guts(dest);
16094 draw_flash(dest);
16095 break;
16096 }
16097
16098 if ( editorflags & ENEMY_FLAG1 ) //visible to Amulet 2
16099 {
16100 if
16101 (
16102 ( (editorflags & ENEMY_FLAG1) && current_item_power(itype_amulet) >= 2 && (editorflags & ENEMY_FLAG15) )
16103 ||
16104 ( (editorflags & ENEMY_FLAG2) && (game->item[dmisc13]) && (editorflags & ENEMY_FLAG15) )
16105 )
16106 {
16107 draw_guts(dest); //makes his shots visible, but not him
16108 draw_flash(dest);
16109 }
16110 }
16111 }
16112
16113 void eGanon::draw_guts(BITMAP *dest)
16114 {
16115 int32_t c = zc_min(clk>>3,8);
16116 tile = clk<24 ? 74 : 75;
16117 overtile16(dest,tile,x+8,y+c+playing_field_offset,9,0);
16118 overtile16(dest,tile,x+8,y+16-c+playing_field_offset,9,0);
16119 overtile16(dest,tile,x+c,y+8+playing_field_offset,9,0);
16120 overtile16(dest,tile,x+16-c,y+8+playing_field_offset,9,0);
16121 overtile16(dest,tile,x+c,y+c+playing_field_offset,9,0);
16122 overtile16(dest,tile,x+16-c,y+c+playing_field_offset,9,0);
16123 overtile16(dest,tile,x+c,y+16-c+playing_field_offset,9,0);
16124 overtile16(dest,tile,x+16-c,y+16-c+playing_field_offset,9,0);
16125 }
16126
16127 void eGanon::draw_flash(BITMAP *dest)
16128 {
16129
16130 int32_t c = clk-(clk>>2);
16131 cs = (frame&3)+6;
16132 overtile16(dest,194,x+8,y+8-clk+playing_field_offset,cs,0);
16133 overtile16(dest,194,x+8,y+8+clk+playing_field_offset,cs,2);
16134 overtile16(dest,195,x+8-clk,y+8+playing_field_offset,cs,0);
16135 overtile16(dest,195,x+8+clk,y+8+playing_field_offset,cs,1);
16136 overtile16(dest,196,x+8-c,y+8-c+playing_field_offset,cs,0);
16137 overtile16(dest,196,x+8+c,y+8-c+playing_field_offset,cs,1);
16138 overtile16(dest,196,x+8-c,y+8+c+playing_field_offset,cs,2);
16139 overtile16(dest,196,x+8+c,y+8+c+playing_field_offset,cs,3);
16140 }
16141 */
16142
16143 eGanon::eGanon(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
16144 {
16145 hxofs=hyofs=8;
16146 if (editorflags & ENEMY_FLAG3)
16147 {
16148 hxofs = 4;
16149 hyofs = 4;
16150 hxsz = 24;
16151 hysz = 24;
16152 SIZEflags|=guyflagOVERRIDE_HIT_WIDTH;
16153 SIZEflags|=guyflagOVERRIDE_HIT_HEIGHT;
16154 }
16155 hzsz=16; //can't be jumped.
16156 clk2=70;
16157 misc=-1;
16158 mainguy=(!getmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM) || (tmpscr->flags9&fBELOWRETURN));
16159 }
16160
16161 bool eGanon::animate(int32_t index) //DO NOT ADD a check for do_animation to this version of GANON!! -Z
16162 {
16163 if(dying)
16164
16165 return Dead(index);
16166
16167 if(clk==0)
16168 {
16169 removearmos(x,y,ffcactivated);
16170 }
16171
16172 switch(misc)
16173 {
16174 case -1:
16175 misc=0;
16176 [[fallthrough]];
16177 case 0:
16178 if(++clk2>72 && !(zc_oldrand()&3))
16179 {
16180 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
16181 sfx(wpnsfx(wpn),pan(int32_t(x)));
16182 clk2=0;
16183 }
16184
16185 Stunclk=0;
16186 constant_walk(rate,homing,spw_none);
16187 break;
16188
16189 case 1:
16190 case 2:
16191 if(--Stunclk<=0)
16192 {
16193 int32_t r=zc_oldrand();
16194
16195 if(r&1)
16196 {
16197 y=96;
16198
16199 if(r&2)
16200 x=160;
16201 else
16202 x=48;
16203
16204 if(tooclose(x,y,48))
16205 x=208-x;
16206 }
16207
16208 loadpalset(csBOSS,pSprite(d->bosspal));
16209 misc=0;
16210 }
16211
16212 break;
16213
16214 case 3:
16215 {
16216 if(hclk>0)
16217 break;
16218
16219 misc=4;
16220 clk=0;
16221 hxofs=1000;
16222 loadpalset(9,pSprite(spPILE));
16223 music_stop();
16224 stop_sfx(WAV_ROAR);
16225
16226 if(deadsfx>0) sfx(deadsfx,pan(int32_t(x)));
16227
16228 sfx(WAV_GANON);
16229 //Ganon's dustpile; fall in sideview. -Z
16230 //item *dustpile = new item(x+8,y+8,(zfix)0,iPile,ipDUMMY,0);
16231 //dustpile->miscellaneous[31] = eeGANON;
16232 items.add(new item(x+8,y+8,(zfix)0,iPile,ipDUMMY,0));
16233 item *dustpile = NULL;
16234 //dustpile = (item *)items.spr(items.Count() - 1)->getUID();
16235 dustpile = (item *)items.spr(items.Count() - 1);
16236 dustpile->linked_parent = eeGANON; //was miscellaneous[31]
16237 //setmapflag(); //Could be why the Triforce doesn't drop. Disabling this now. -Z ( 6th March, 2019 )
16238 //items.add(new item(x+8,y+8,(zfix)0,iPile,ipDUMMY,0));
16239 break;
16240 }
16241
16242 case 4:
16243 if(clk>=80)
16244 {
16245 misc=5;
16246
16247 //game->lvlitems[dlevel]|=liBOSS;
16248
16249 sfx(WAV_CLEARED);
16250 //Add the big TF over the ashes!
16251 for(word q = 0; q < items.Count(); q++)
16252 {
16253 item *ashes = (item*)items.spr(q);
16254 if ( ashes->linked_parent == eeGANON && (ashes->pickup&ipDUMMY))
16255 {
16256 //Z_scripterrlog("Found correct dustpile!\n");
16257 items.add(new item(ashes->x,ashes->y,(zfix)0,iBigTri,ipBIGTRI,0));
16258 item *bigtriforce = NULL;
16259 bigtriforce = (item *)items.spr(items.Count() - 1);
16260 bigtriforce->linked_parent = eeGANON;
16261 }
16262 }
16263 //setmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM);
16264 //game->lvlitems[dlevel]|=liBOSS; // if we had more rule bits, we could mark him dead so that he does not respawn. -Z
16265 }
16266
16267 break;
16268 case 5: return true;
16269 }
16270
16271 return enemy::animate(index);
16272 }
16273
16274
16275 int32_t eGanon::takehit(weapon *w)
16276 {
16277 //these are here to bypass compiler warnings about unused arguments
16278 int32_t wpnId = w->id;
16279 int32_t power = w->power;
16280 int32_t enemyHitWeapon = w->parentitem;
16281
16282 switch(misc)
16283 {
16284 case 0:
16285 if(wpnId!=wSword)
16286 return 0;
16287
16288 hp-=power;
16289
16290 if(hp>0)
16291 {
16292 misc=1;
16293 Stunclk=64;
16294 }
16295 else
16296 {
16297 loadpalset(csBOSS,pSprite(spBROWN));
16298 misc=2;
16299 Stunclk=284;
16300 hp=guysbuf[id&0xFFF].hp; //16*game->get_hero_dmgmult();
16301 }
16302
16303 sfx(WAV_EHIT,pan(int32_t(x)));
16304
16305 if(hitsfx>0) sfx(hitsfx,pan(int32_t(x)));
16306
16307 return 1;
16308
16309 case 2:
16310 if(wpnId!=wArrow || (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_arrow))<4)
16311 return 0;
16312
16313 misc=3;
16314 hclk=81;
16315 loadpalset(9,pSprite(spBROWN));
16316 return 1;
16317 }
16318
16319 return 0;
16320 }
16321
16322 void eGanon::draw(BITMAP *dest)
16323 {
16324 switch(misc)
16325 {
16326 case 0:
16327 if((clk&3)==3)
16328 tile=(zc_oldrand()%5)*2+o_tile;
16329
16330 if ( (editorflags & ENEMY_FLAG1) && current_item_power(itype_amulet) >= 2 ) //ganon is visible to level 2 amulet
16331 {
16332
16333 if ( editorflags & ENEMY_FLAG16 ) //draw cloaked
16334 {
16335 int odraw = drawstyle;
16336 drawstyle = 2;
16337 drawblock(dest,15);
16338 drawstyle = odraw;
16339 }
16340 else
16341 {
16342 drawblock(dest,15);
16343 }
16344 break;
16345
16346 }
16347 else if ( (editorflags & ENEMY_FLAG2) && (game->item[dmisc13]) )
16348 {
16349 if ( editorflags & ENEMY_FLAG16 ) //draw cloaked
16350 {
16351 int odraw = drawstyle;
16352 drawstyle = 2;
16353 drawblock(dest,15);
16354 drawstyle = odraw;
16355 }
16356 else
16357 {
16358 drawblock(dest,15);
16359 }
16360 break;
16361 }
16362 if(db!=999)
16363 break;
16364 [[fallthrough]];
16365 case 2:
16366 if(Stunclk<64 && (Stunclk&1))
16367 break;
16368 [[fallthrough]];
16369 case -1:
16370 tile=o_tile;
16371
16372 [[fallthrough]];
16373 case 1:
16374 case 3:
16375 drawblock(dest,15);
16376 break;
16377
16378 case 4:
16379 draw_guts(dest);
16380 draw_flash(dest);
16381 break;
16382 }
16383 }
16384
16385 void eGanon::draw_guts(BITMAP *dest)
16386 {
16387 int32_t c = zc_min(clk>>3,8);
16388 tile = clk<24 ? 74 : 75;
16389 overtile16(dest,tile,x+8,y+c+playing_field_offset,9,0);
16390 overtile16(dest,tile,x+8,y+16-c+playing_field_offset,9,0);
16391 overtile16(dest,tile,x+c,y+8+playing_field_offset,9,0);
16392 overtile16(dest,tile,x+16-c,y+8+playing_field_offset,9,0);
16393 overtile16(dest,tile,x+c,y+c+playing_field_offset,9,0);
16394 overtile16(dest,tile,x+16-c,y+c+playing_field_offset,9,0);
16395 overtile16(dest,tile,x+c,y+16-c+playing_field_offset,9,0);
16396 overtile16(dest,tile,x+16-c,y+16-c+playing_field_offset,9,0);
16397 }
16398
16399 void eGanon::draw_flash(BITMAP *dest)
16400 {
16401
16402 int32_t c = clk-(clk>>2);
16403 cs = (frame&3)+6;
16404 overtile16(dest,194,x+8,y+8-clk+playing_field_offset,cs,0);
16405 overtile16(dest,194,x+8,y+8+clk+playing_field_offset,cs,2);
16406 overtile16(dest,195,x+8-clk,y+8+playing_field_offset,cs,0);
16407 overtile16(dest,195,x+8+clk,y+8+playing_field_offset,cs,1);
16408 overtile16(dest,196,x+8-c,y+8-c+playing_field_offset,cs,0);
16409 overtile16(dest,196,x+8+c,y+8-c+playing_field_offset,cs,1);
16410 overtile16(dest,196,x+8-c,y+8+c+playing_field_offset,cs,2);
16411 overtile16(dest,196,x+8+c,y+8+c+playing_field_offset,cs,3);
16412 }
16413
16414 void getBigTri(int32_t id2)
16415 {
16416 /*
16417 *************************
16418 * BIG TRIFORCE SEQUENCE *
16419 *************************
16420 0 BIGTRI out, WHITE flash in
16421 4 WHITE flash out, PILE cset white
16422 8 WHITE in
16423 ...
16424 188 WHITE out
16425 191 PILE cset red
16426 200 top SHUTTER opens
16427 209 bottom SHUTTER opens
16428 */
16429 sfx(itemsbuf[id2].playsound);
16430 guys.clear();
16431
16432 if(itemsbuf[id2].flags & ITEM_GAMEDATA)
16433 {
16434 game->lvlitems[dlevel]|=liTRIFORCE;
16435 }
16436
16437 setmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM);
16438
16439 draw_screen(tmpscr);
16440
16441 for(int32_t f=0; f<24*8 && !Quit; f++)
16442 {
16443 if(f==4)
16444 {
16445 for(int32_t i=1; i<16; i++)
16446 {
16447 RAMpal[CSET(9)+i]=_RGB(63,63,63);
16448 }
16449 }
16450
16451 if((f&7)==0)
16452 {
16453 for(int32_t cs=2; cs<5; cs++)
16454 {
16455 for(int32_t i=1; i<16; i++)
16456 {
16457 RAMpal[CSET(cs)+i]=_RGB(63,63,63);
16458 }
16459 }
16460
16461 refreshpal=true;
16462 }
16463
16464 if((f&7)==4)
16465 {
16466 if(currscr<128) loadlvlpal(DMaps[currdmap].color);
16467 else loadlvlpal(0xB);
16468 }
16469
16470 if(f==191)
16471 {
16472 loadpalset(9,pSprite(spPILE));
16473 }
16474
16475 advanceframe(true);
16476 }
16477
16478 //play_DmapMusic();
16479 playLevelMusic();
16480
16481 if(itemsbuf[id2].flags & ITEM_FLAG1 && currscr < 128)
16482 {
16483 Hero.dowarp(1,0); //side warp
16484 }
16485 }
16486
16487 /**********************************/
16488 /*** Multiple-Segment Enemies ***/
16489 /**********************************/
16490
16491
16492 //! No. I am not adding SIZEflags to Moldorm and Lanmola. -Z 12 Aug 2020
16493 eMoldorm::eMoldorm(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
16494 {
16495 if( !(editorflags & ENEMY_FLAG5) )
16496 {
16497 x=128;
16498 y=48;
16499 }
16500 //else { x = X; y = Y; }
16501 dir=(zc_oldrand()&7)+8;
16502 superman=1;
16503 fading=fade_invisible;
16504 hxofs=1000;
16505 segcnt=clk;
16506 segid=Id|0x1000;
16507 clk=0;
16508 id=guys.Count();
16509 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
16510 tile=o_tile;
16511 hitdir = -1;
16512 stickclk = 0;
16513
16514 /*
16515 if (get_bit(quest_rules,qr_NEWENEMYTILES))
16516 {
16517 tile=nets+1220;
16518 }
16519 else
16520 {
16521 tile=57;
16522 }
16523 */
16524 }
16525
16526 bool eMoldorm::animate(int32_t index)
16527 {
16528 if(switch_hooked) return enemy::animate(index);
16529 int32_t max_y = isdungeon() ? 100 : 100+28; //warning: Ugly hack. -Z
16530 if ( y > (max_y) )
16531 {
16532 ++stickclk; //Keep Moldorm from pacinn the bottom row or leaving the screen via the bottom edge. -Z 8th Sept, 2019
16533 //Z_scripterrlog("Stickclk is %d\n", stickclk);
16534 }
16535 if ( stickclk > 45 )
16536 {
16537 stickclk = 0;
16538 newdir_8_old(rate,homing,spw_floater); //chage dir to keep from getting stuck.
16539 }
16540
16541
16542 if(clk==0)
16543 {
16544 removearmos(x,y,ffcactivated);
16545 }
16546
16547 if(clk2)
16548 {
16549 if(--clk2 == 0)
16550 {
16551 if(flags&guy_neverret)
16552 never_return(index);
16553
16554 if(!dmisc2 || (editorflags & ENEMY_FLAG6))
16555 leave_item();
16556
16557 stop_bgsfx(index);
16558 return true;
16559 }
16560 }
16561 else
16562 {
16563 if(stunclk>0)
16564 stunclk=0;
16565 constant_walk_8_old(rate,homing,spw_floater);
16566
16567
16568 misc=dir;
16569
16570 // If any higher-numbered segments were killed, segcnt can be too high,
16571 // leading to a crash
16572 if(index+segcnt>=guys.Count())
16573 segcnt=guys.Count()-index-1;
16574
16575 for(int32_t i=index+1; i<index+segcnt+1; i++)
16576 {
16577 enemy* segment=((enemy*)guys.spr(i));
16578
16579 // More validation - if segcnt was wrong, this may not
16580 // actually be a Moldorm segment
16581 if(segment->id!=segid)
16582 {
16583 segcnt=i-index-1;
16584 break;
16585 }
16586
16587 if(i==index+1)
16588 {
16589 x=segment->x;
16590 y=segment->y;
16591 }
16592
16593 segment->o_tile=tile; //I refuse to fuck with adding scripttile to segmented enemies. -Z
16594 //Script your own blasted segmented bosses!! -Z
16595 segment->parent_script_UID = this->script_UID;
16596 if((i==index+segcnt)&&(i!=index+1)) //tail
16597 {
16598 segment->dummy_int[1]=2;
16599 }
16600 else
16601 {
16602 segment->dummy_int[1]=1;
16603 }
16604
16605 if(i==index+1) //head
16606 {
16607 segment->dummy_int[1]=0;
16608 }
16609
16610 if(segment->hp <= 0)
16611 {
16612 int32_t offset=1;
16613
16614 for(int32_t j=i; j<index+segcnt; j++)
16615 {
16616 // Triple-check
16617 if(((enemy*)guys.spr(j+1))->id!=segid)
16618 {
16619 segcnt=j-index+1; // Add 1 because of --segcnt below
16620 break;
16621 }
16622 zc_swap(((enemy*)guys.spr(j))->hp,((enemy*)guys.spr(j+1))->hp);
16623 zc_swap(((enemy*)guys.spr(j))->hclk,((enemy*)guys.spr(j+1))->hclk);
16624 }
16625
16626 segment->hclk=33;
16627 --segcnt;
16628 --i; // Recheck the same index in case multiple segments died at once
16629 }
16630 }
16631
16632 if(segcnt==0)
16633 {
16634 clk2=19;
16635
16636 x=guys.spr(index+1)->x;
16637 y=guys.spr(index+1)->y;
16638 }
16639 }
16640
16641 return false;
16642 }
16643
16644 esMoldorm::esMoldorm(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
16645 {
16646 if( !(editorflags & ENEMY_FLAG5) )
16647 {
16648 x=128;
16649 y=48;
16650 }
16651
16652 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
16653 hyofs=4;
16654 hxsz=hysz=8;
16655 hxofs=1000;
16656 mainguy=count_enemy=false;
16657 parentclk = 0;
16658 bgsfx=-1;
16659 flags&=~guy_neverret;
16660 //deadsfx = WAV_EDEAD;
16661 isCore = false;
16662 }
16663
16664 bool esMoldorm::animate(int32_t index)
16665 {
16666 if(switch_hooked) return enemy::animate(index);
16667 // Shouldn't be possible, but better to be sure
16668 if(index==0)
16669 dying=true;
16670
16671 if(dying)
16672 {
16673 if(!dmisc2)
16674 item_set=0;
16675
16676 return Dead(index);
16677 }
16678
16679 if(clk>=0)
16680 {
16681 hxofs=4;
16682 step=((enemy*)guys.spr(index-1))->step;
16683
16684 if(parentclk == 0)
16685 {
16686 misc=dir;
16687 dir=((enemy*)guys.spr(index-1))->misc;
16688 //do alignment, as in parent's animation :-/ -DD
16689 x.doFloor();
16690 y.doFloor();
16691 }
16692
16693 parentclk=(parentclk+1)%((int32_t)(8.0/step));
16694
16695 if(!watch)
16696 {
16697 sprite::move(step);
16698 }
16699 }
16700
16701 return enemy::animate(index);
16702 }
16703
16704 int32_t esMoldorm::takehit(weapon *w)
16705 {
16706 if(enemy::takehit(w))
16707 return (w->id==wSBomb) ? 1 : 2; // force it to wait a frame before checking sword attacks again
16708
16709 return 0;
16710 }
16711
16712 void esMoldorm::draw(BITMAP *dest)
16713 {
16714 tile=o_tile;
16715 int32_t fdiv = frate/4;
16716 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
16717
16718 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
16719 efrate:((clk>=(frate>>1))?1:0);
16720
16721 if(get_bit(quest_rules,qr_NEWENEMYTILES))
16722 {
16723 tile+=dummy_int[1]*40;
16724
16725 if(dir<8)
16726 {
16727 flip=0;
16728 tile+=4*zc_max(dir, 0); // dir is -1 if trapped
16729
16730 if(dir>3) // Skip to the next row for diagonals
16731 tile+=4;
16732 }
16733 else
16734 {
16735 switch(dir-8) //directions get screwed up after 8. *shrug*
16736 {
16737 case up: //u
16738 flip=0;
16739 break;
16740
16741 case l_up: //d
16742 flip=0;
16743 tile+=4;
16744 break;
16745
16746 case l_down: //l
16747 flip=0;
16748 tile+=8;
16749 break;
16750
16751 case left: //r
16752 flip=0;
16753 tile+=12;
16754 break;
16755
16756 case r_down: //ul
16757 flip=0;
16758 tile+=20;
16759 break;
16760
16761 case down: //ur
16762 flip=0;
16763 tile+=24;
16764 break;
16765
16766 case r_up: //dl
16767 flip=0;
16768 tile+=28;
16769 break;
16770
16771 case right: //dr
16772 flip=0;
16773 tile+=32;
16774 break;
16775 }
16776 }
16777
16778 tile+=f2;
16779 }
16780
16781 if(clk>=0)
16782 enemy::draw(dest);
16783 }
16784
16785 eLanmola::eLanmola(zfix X,zfix Y,int32_t Id,int32_t Clk) : eBaseLanmola(X,Y,Id,Clk)
16786 {
16787 if( !(editorflags & ENEMY_FLAG5) )
16788 {
16789 x=64;
16790 y=80;
16791 }
16792 //else { x = X; y = Y; }
16793 //zprint2("lanmola index is %d\n", index);
16794 //byte legaldirs = 0;
16795 int32_t incr = 16;
16796 //int32_t possiiblepos = 0;
16797 //int32_t positions[8] = {0};
16798
16799 //Don't spawn in pits.
16800 if ( m_walkflag_simple(x, y) )
16801 {
16802 //zprint2("Can't spawn here.\n");
16803 for ( ; incr < 240; incr += 16 )
16804 {
16805 //move if we spawn over a pit
16806 //check each direction
16807 if ( !m_walkflag_simple(x-incr, y) ) //legaldirs |= 0x1; //left
16808 {
16809 //zprint2("Spawn adjustment: -x (%d)\n", incr);
16810 x-=incr; break;
16811 }
16812 else if ( !m_walkflag_simple(x+incr, y) ) //legaldirs |= 0x2; //right
16813 {
16814 //zprint2("Spawn adjustment: +x (%d)\n", incr);
16815 x+=incr; break;
16816 }
16817 else if ( !m_walkflag_simple(x-incr, y-incr) ) //legaldirs |= 0x4; //left-up
16818 {
16819 //zprint2("Spawn adjustment: -x (%d), -y (%d)\n", incr, incr);
16820 x-=incr; y-=incr; break;
16821 }
16822 else if ( !m_walkflag_simple(x+incr, y-incr) ) //legaldirs |= 0x8; //right-up
16823 {
16824 //zprint2("Spawn adjustment: +x (%d), -y (%d)\n", incr, incr);
16825 x+=incr; y-=incr; break;
16826 }
16827 else if ( !m_walkflag_simple(x, y-incr) ) // legaldirs |= 0x10; //up
16828 {
16829 //zprint2("Spawn adjustment: -y (%d)\n", incr);
16830 y -= incr; break;
16831 }
16832 else if ( !m_walkflag_simple(x, y+incr) ) //legaldirs |= 0x20; //down
16833 {
16834 //zprint2("Spawn adjustment: +y (%d)\n", incr);
16835 y+=incr; break;
16836 }
16837 else if ( !m_walkflag_simple(x-incr, y+incr) ) //legaldirs |= 0x40; //left-down
16838 {
16839 //zprint2("Spawn adjustment: -x (%d), +y (%d)\n", incr, incr);
16840 x-=incr; y+=incr; break;
16841 }
16842 else if ( !m_walkflag_simple(x+incr, y+incr) ) //legaldirs |= 0x80; //right-down
16843 {
16844 //zprint2("Spawn adjustment: +x (%d), +y (%d)\n", incr, incr);
16845 x+=incr; y+=incr; break;
16846 }
16847 else continue;
16848
16849 }
16850
16851 }
16852
16853 dir=up;
16854 superman=1;
16855 fading=fade_invisible;
16856 hxofs=1000;
16857 segcnt=clk;
16858 clk=0;
16859 //set up move history
16860 for(int32_t i=0; i <= (1<<dmisc2); i++)
16861 prevState.push_back(std::pair<std::pair<zfix, zfix>, int32_t>(std::pair<zfix,zfix>(x,y), dir));
16862 }
16863
16864 bool eLanmola::animate(int32_t index)
16865 {
16866 if(switch_hooked) return enemy::animate(index);
16867 if(clk==0)
16868 {
16869 removearmos(x,y,ffcactivated);
16870 }
16871
16872 if(clk2)
16873 {
16874 if(--clk2 == 0)
16875 {
16876 if(!dmisc3) //This checks if "segments drop items" isn't true, because if they don't drop items, then only killing the whole thing drops an item.
16877 leave_item();
16878
16879 stop_bgsfx(index);
16880 return true;
16881 }
16882
16883 return false;
16884 }
16885
16886
16887 //this animation style plays ALL KINDS of havoc on the Lanmola segments, since it causes
16888 //the direction AND x,y position of the lanmola to vary in uncertain ways.
16889 //I've added a complete movement history to this enemy to compensate -DD
16890 constant_walk(rate,homing,spw_none);
16891 prevState.pop_front();
16892 prevState.push_front(std::pair<std::pair<zfix, zfix>, int32_t>(std::pair<zfix, zfix>(x,y), dir));
16893
16894 // This could cause a crash with Moldorms. I didn't see the same problem
16895 // with Lanmolas, but it looks like it ought to be possible, so here's
16896 // the same solution. - Saf
16897 if(index+segcnt>=guys.Count())
16898 segcnt=guys.Count()-index-1;
16899
16900 for(int32_t i=index+1; i<index+segcnt+1; i++)
16901 {
16902 enemy* segment=((enemy*)guys.spr(i));
16903
16904 // More validation in case segcnt is wrong
16905 if((segment->id&0xFFF)!=(id&0xFFF))
16906 {
16907 segcnt=i-index-1;
16908 break;
16909 }
16910
16911 segment->o_tile=o_tile;
16912 segment->parent_script_UID = this->script_UID;
16913 if((i==index+segcnt)&&(i!=index+1))
16914 {
16915 segment->dummy_int[1]=1; //tail
16916 }
16917 else
16918 {
16919 segment->dummy_int[1]=0;
16920 }
16921
16922 if(segment->hp <= 0)
16923 {
16924 for(int32_t j=i; j<index+segcnt; j++)
16925 {
16926 // Triple-check
16927 if((((enemy*)guys.spr(j+1))->id&0xFFF)!=(id&0xFFF))
16928 {
16929 segcnt=j-index+1; // Add 1 because of --segcnt below
16930 break;
16931 }
16932 zc_swap(((enemy*)guys.spr(j))->hp,((enemy*)guys.spr(j+1))->hp);
16933 zc_swap(((enemy*)guys.spr(j))->hclk,((enemy*)guys.spr(j+1))->hclk);
16934 }
16935
16936 ((enemy*)guys.spr(i))->hclk=33;
16937 --segcnt;
16938 --i; // Recheck the same index in case multiple segments died at once
16939 }
16940 }
16941
16942 if(segcnt==0)
16943 {
16944 clk2=19;
16945 x=guys.spr(index+1)->x;
16946 y=guys.spr(index+1)->y;
16947 setmapflag(mTMPNORET);
16948 }
16949
16950 //this enemy is invincible.. BUT scripts don't know that, and can "kill" it by setting the hp negative.
16951 //which is... disastrous.
16952 hp = 1;
16953 return enemy::animate(index);
16954 }
16955
16956 esLanmola::esLanmola(zfix X,zfix Y,int32_t Id,int32_t Clk) : eBaseLanmola(X,Y,Id,Clk)
16957 {
16958 if( !(editorflags & ENEMY_FLAG5) )
16959 {
16960 x=64;
16961 y=80;
16962 }
16963 int32_t incr = 16;
16964 //Don't spawn in pits.
16965 if ( m_walkflag_simple(x, y) )
16966 {
16967 //zprint2("Can't spawn here.\n");
16968 for ( ; incr < 240; incr += 16 )
16969 {
16970 //move if we spawn over a pit
16971 //check each direction
16972 if ( !m_walkflag_simple(x-incr, y) ) //legaldirs |= 0x1; //left
16973 {
16974 //zprint2("Spawn adjustment: -x (%d)\n", incr);
16975 x-=incr; break;
16976 }
16977 else if ( !m_walkflag_simple(x+incr, y) ) //legaldirs |= 0x2; //right
16978 {
16979 //zprint2("Spawn adjustment: +x (%d)\n", incr);
16980 x+=incr; break;
16981 }
16982 else if ( !m_walkflag_simple(x-incr, y-incr) ) //legaldirs |= 0x4; //left-up
16983 {
16984 //zprint2("Spawn adjustment: -x (%d), -y (%d)\n", incr, incr);
16985 x-=incr; y-=incr; break;
16986 }
16987 else if ( !m_walkflag_simple(x+incr, y-incr) ) //legaldirs |= 0x8; //right-up
16988 {
16989 //zprint2("Spawn adjustment: +x (%d), -y (%d)\n", incr, incr);
16990 x+=incr; y-=incr; break;
16991 }
16992 else if ( !m_walkflag_simple(x, y-incr) ) // legaldirs |= 0x10; //up
16993 {
16994 //zprint2("Spawn adjustment: -y (%d)\n", incr);
16995 y -= incr; break;
16996 }
16997 else if ( !m_walkflag_simple(x, y+incr) ) //legaldirs |= 0x20; //down
16998 {
16999 //zprint2("Spawn adjustment: +y (%d)\n", incr);
17000 y+=incr; break;
17001 }
17002 else if ( !m_walkflag_simple(x-incr, y+incr) ) //legaldirs |= 0x40; //left-down
17003 {
17004 //zprint2("Spawn adjustment: -x (%d), +y (%d)\n", incr, incr);
17005 x-=incr; y+=incr; break;
17006 }
17007 else if ( !m_walkflag_simple(x+incr, y+incr) ) //legaldirs |= 0x80; //right-down
17008 {
17009 //zprint2("Spawn adjustment: +x (%d), +y (%d)\n", incr, incr);
17010 x+=incr; y+=incr; break;
17011 }
17012 else continue;
17013
17014 }
17015
17016 }
17017
17018 hxofs=1000;
17019 hxsz=8;
17020 mainguy=false;
17021 count_enemy=(id<0x2000)?true:false;
17022
17023 //set up move history
17024 for(int32_t i=0; i <= (1<<dmisc2); i++)
17025 prevState.push_back(std::pair<std::pair<zfix, zfix>, int32_t>(std::pair<zfix,zfix>(x,y), dir));
17026
17027 bgsfx = -1;
17028 isCore = false;
17029 flags&=~guy_neverret;
17030 }
17031
17032 bool esLanmola::animate(int32_t index)
17033 {
17034 if(switch_hooked) return enemy::animate(index);
17035 // Shouldn't be possible, but who knows
17036 if(index==0)
17037 dying=true;
17038
17039 if(dying)
17040 {
17041 xofs=0;
17042
17043 if(!dmisc3)
17044 item_set=0;
17045
17046 return Dead(index);
17047 }
17048
17049 if(clk>=0)
17050 {
17051 hxofs=4;
17052
17053 if(!watch)
17054 {
17055 std::pair<std::pair<zfix, zfix>, int32_t> newstate = ((eBaseLanmola*)guys.spr(index-1))->prevState.front();
17056 prevState.pop_front();
17057 prevState.push_back(newstate);
17058 x = newstate.first.first;
17059 y = newstate.first.second;
17060 dir = newstate.second;
17061 }
17062 }
17063
17064 return enemy::animate(index);
17065 }
17066
17067 int32_t esLanmola::takehit(weapon *w)
17068 {
17069 if(enemy::takehit(w))
17070 return (w->id==wSBomb) ? 1 : 2; // force it to wait a frame before checking sword attacks again
17071
17072 return 0;
17073 }
17074
17075 void esLanmola::draw(BITMAP *dest)
17076 {
17077 tile=o_tile;
17078 int32_t fdiv = frate/4;
17079 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
17080
17081 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
17082 efrate:((clk>=(frate>>1))?1:0);
17083
17084 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17085 {
17086 if(id>=0x2000)
17087 {
17088 tile+=20;
17089
17090 if(dummy_int[1]==1)
17091 {
17092 tile+=20;
17093 }
17094 }
17095
17096 switch(dir)
17097 {
17098 case up:
17099 flip=0;
17100 break;
17101
17102 case down:
17103 flip=0;
17104 tile+=4;
17105 break;
17106
17107 case left:
17108 flip=0;
17109 tile+=8;
17110 break;
17111
17112 case right:
17113 flip=0;
17114 tile+=12;
17115 break;
17116 }
17117
17118 tile+=f2;
17119 }
17120 else
17121 {
17122 if(id>=0x2000)
17123 {
17124 tile+=1;
17125 }
17126 }
17127
17128 if(clk>=0)
17129 enemy::draw(dest);
17130 }
17131
17132 eManhandla::eManhandla(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,0)
17133 {
17134 //these are here to bypass compiler warnings about unused arguments
17135 Clk=Clk;
17136 superman=1;
17137 dir=(zc_oldrand()&7)+8;
17138 armcnt=dmisc2?8:4;//((id==eMANHAN)?4:8);
17139
17140 for(int32_t i=0; i<armcnt; i++)
17141 arm[i]=i;
17142
17143 fading=fade_blue_poof;
17144 //nets+4680;
17145 adjusted=false;
17146 SIZEflags = d->SIZEflags; //Probably will be buggy. -Z 12 AUG 2020
17147 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
17148 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
17149 // al_trace("Enemy txsz:%i\n", txsz);
17150 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
17151 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
17152 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
17153 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
17154 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
17155 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
17156 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
17157 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
17158 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
17159 {
17160 yofs = d->yofs+(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
17161 }
17162
17163 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
17164 }
17165
17166 bool eManhandla::animate(int32_t index)
17167 {
17168 if(switch_hooked) return enemy::animate(index);
17169 if(dying)
17170 return Dead(index);
17171
17172 if(clk==0)
17173 {
17174 removearmos(x,y,ffcactivated);
17175 }
17176
17177
17178 // check arm status, move dead ones to end of group
17179 for(int32_t i=0; i<armcnt; i++)
17180 {
17181 enemy* cur_arm = ((enemy*)guys.spr(index+i+1));
17182 if(!cur_arm || cur_arm->dying)
17183 {
17184 for(int32_t j=i; j<armcnt-1; j++)
17185 {
17186 zc_swap(arm[j],arm[j+1]);
17187 guys.swap(index+j+1,index+j+2);
17188 }
17189 if((editorflags & ENEMY_FLAG6)) //They only did this in 2.10
17190 {
17191 leave_item();
17192 }
17193 --armcnt;
17194 --i;
17195 continue;
17196 }
17197 if(!adjusted)
17198 {
17199 if(!dmisc2)
17200 {
17201 cur_arm->o_tile=o_tile+40;
17202 cur_arm->parent_script_UID = this->script_UID;
17203 }
17204 else
17205 {
17206 cur_arm->o_tile=o_tile+160;
17207 cur_arm->parent_script_UID = this->script_UID;
17208 }
17209 }
17210 }
17211
17212 adjusted=true;
17213
17214 // move or die
17215 if(armcnt==0)
17216 hp=0;
17217 else
17218 {
17219 // Speed starts at 0.5, and increases by 0.5 for each head lost. Max speed is 4.5.
17220 step=zc_min(zfix(4.5),(((!dmisc2)?4:8)-int64_t(armcnt))*0.5+zslongToFix(dstep*100));
17221 int32_t dx1=0, dy1=-8, dx2=15, dy2=15;
17222
17223 if(!dmisc2)
17224 {
17225 for(int32_t i=0; i<armcnt; i++)
17226 {
17227 switch(arm[i])
17228 {
17229 case 0:
17230 dy1=-24;
17231 break;
17232
17233 case 1:
17234 dy2=31;
17235 break;
17236
17237 case 2:
17238 dx1=-16;
17239 break;
17240
17241 case 3:
17242 dx2=31;
17243 break;
17244 }
17245 }
17246 }
17247 else
17248 {
17249 dx1=-8, dy1=-16, dx2=23, dy2=23;
17250
17251 for(int32_t i=0; i<armcnt; i++)
17252 {
17253 switch(arm[i]&3)
17254 {
17255 case 0:
17256 dy1=-32;
17257 break;
17258
17259 case 1:
17260 dy2=39;
17261 break;
17262
17263 case 2:
17264 dx1=-24;
17265 break;
17266
17267 case 3:
17268 dx2=39;
17269 break;
17270 }
17271 }
17272 }
17273
17274 variable_walk_8(rate,homing,hrate,spw_floater,dx1,dy1,dx2,dy2);
17275
17276 for(int32_t i=0; i<armcnt; i++)
17277 {
17278 zfix dx=(zfix)0,dy=(zfix)0;
17279
17280 if(!dmisc2)
17281 {
17282 switch(arm[i])
17283 {
17284 case 0:
17285 dy=-16;
17286 break;
17287
17288 case 1:
17289 dy=16;
17290 break;
17291
17292 case 2:
17293 dx=-16;
17294 break;
17295
17296 case 3:
17297 dx=16;
17298 break;
17299 }
17300 }
17301 else
17302 {
17303 switch(arm[i])
17304 {
17305 case 0:
17306 dy=-24;
17307 dx=-8;
17308 break;
17309
17310 case 1:
17311 dy=24;
17312 dx=8;
17313 break;
17314
17315 case 2:
17316 dx=-24;
17317 dy=8;
17318 break;
17319
17320 case 3:
17321 dx=24;
17322 dy=-8;
17323 break;
17324
17325 case 4:
17326 dy=-24;
17327 dx=8;
17328 break;
17329
17330 case 5:
17331 dy=24;
17332 dx=-8;
17333 break;
17334
17335 case 6:
17336 dx=-24;
17337 dy=-8;
17338 break;
17339
17340 case 7:
17341 dx=24;
17342 dy=8;
17343 break;
17344 }
17345 }
17346
17347 guys.spr(index+i+1)->x = x+dx;
17348 guys.spr(index+i+1)->y = y+dy;
17349 }
17350 }
17351
17352 return enemy::animate(index);
17353 }
17354
17355
17356 int32_t eManhandla::takehit(weapon *w)
17357 {
17358 int32_t wpnId = w->id;
17359
17360 if(dying)
17361 return 0;
17362
17363 switch(wpnId)
17364 {
17365 case wBomb:
17366 case wSBomb:
17367 case wSword:
17368 case wHammer:
17369 case wWand:
17370 if (get_bit(quest_rules, qr_MANHANDLA_BLOCK_SFX)) sfx(WAV_EHIT,pan(int32_t(x)));
17371
17372 case wLitBomb:
17373 case wLitSBomb:
17374 case wBait:
17375 case wWhistle:
17376 case wFire:
17377 case wWind:
17378 case wSSparkle:
17379 case wFSparkle:
17380 case wPhantom:
17381 return 0;
17382
17383 case wHookshot:
17384 case wBrang:
17385 sfx(WAV_CHINK,pan(int32_t(x)));
17386 break;
17387
17388 default:
17389 if (get_bit(quest_rules, qr_MANHANDLA_BLOCK_SFX)) sfx(WAV_EHIT,pan(int32_t(x)));
17390 else sfx(WAV_CHINK,pan(int32_t(x)));
17391
17392 }
17393
17394 return 1;
17395 }
17396
17397 void eManhandla::draw(BITMAP *dest)
17398 {
17399 tile=o_tile;
17400 int32_t fdiv = frate/4;
17401 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
17402
17403 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
17404 efrate:((clk>=(frate>>1))?1:0);
17405
17406 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17407 {
17408 if(!dmisc2)
17409 {
17410 switch(dir-8) //directions get screwed up after 8. *shrug*
17411 {
17412 case up: //u
17413 flip=0;
17414 break;
17415
17416 case l_up: //d
17417 flip=0;
17418 tile+=4;
17419 break;
17420
17421 case l_down: //l
17422 flip=0;
17423 tile+=8;
17424 break;
17425
17426 case left: //r
17427 flip=0;
17428 tile+=12;
17429 break;
17430
17431 case r_down: //ul
17432 flip=0;
17433 tile+=20;
17434 break;
17435
17436 case down: //ur
17437 flip=0;
17438 tile+=24;
17439 break;
17440
17441 case r_up: //dl
17442 flip=0;
17443 tile+=28;
17444 break;
17445
17446 case right: //dr
17447 flip=0;
17448 tile+=32;
17449 break;
17450 }
17451
17452 tile+=f2;
17453 enemy::draw(dest);
17454 } //manhandla 2, big body
17455 else
17456 {
17457
17458 switch(dir-8) //directions get screwed up after 8. *shrug*
17459 {
17460 case up: //u
17461 flip=0;
17462 break;
17463
17464 case l_up: //d
17465 flip=0;
17466 tile+=8;
17467 break;
17468
17469 case l_down: //l
17470 flip=0;
17471 tile+=40;
17472 break;
17473
17474 case left: //r
17475 flip=0;
17476 tile+=48;
17477 break;
17478
17479 case r_down: //ul
17480 flip=0;
17481 tile+=80;
17482 break;
17483
17484 case down: //ur
17485 flip=0;
17486 tile+=88;
17487 break;
17488
17489 case r_up: //dl
17490 flip=0;
17491 tile+=120;
17492 break;
17493
17494 case right: //dr
17495 flip=0;
17496 tile+=128;
17497 break;
17498 }
17499
17500 tile+=(f2*2);
17501 xofs-=8;
17502 yofs-=8;
17503 drawblock(dest,15);
17504 xofs+=8;
17505 yofs+=8;
17506 }
17507 }
17508 else
17509 {
17510 if(!dmisc2)
17511 {
17512 enemy::draw(dest);
17513 }
17514 else
17515 {
17516 xofs-=8;
17517 yofs-=8;
17518 enemy::draw(dest);
17519 xofs+=16;
17520 enemy::draw(dest);
17521 yofs+=16;
17522 enemy::draw(dest);
17523 xofs-=16;
17524 enemy::draw(dest);
17525 xofs+=8;
17526 yofs-=8;
17527 }
17528 }
17529 }
17530
17531 esManhandla::esManhandla(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
17532 {
17533 id=misc=clk;
17534 dir = clk & 3;
17535 clk=0;
17536 mainguy=count_enemy=false;
17537 dummy_bool[0]=false;
17538 item_set=0;
17539 bgsfx=-1;
17540 deadsfx = WAV_EDEAD;
17541 flags &= (~guy_neverret);
17542 isCore = false;
17543 //Probably will be buggy. -Z 12 AUG 2020
17544 SIZEflags = d->SIZEflags;
17545 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
17546 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
17547 // al_trace("Enemy txsz:%i\n", txsz);
17548 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
17549 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
17550 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
17551 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
17552 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
17553 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
17554 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
17555 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
17556 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
17557 {
17558 yofs = d->yofs+(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
17559 }
17560
17561 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
17562 }
17563
17564 bool esManhandla::animate(int32_t index)
17565 {
17566 if(switch_hooked) return enemy::animate(index);
17567 if(dying)
17568 return Dead(index);
17569
17570 if(clk==0)
17571 {
17572 removearmos(x,y,ffcactivated);
17573 }
17574
17575 if(--clk2<=0)
17576 {
17577 clk2=unsigned(zc_oldrand())%5+5;
17578 clk3^=1;
17579 }
17580
17581 if(!(zc_oldrand()&127))
17582 {
17583 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
17584 sfx(wpnsfx(wpn),pan(int32_t(x)));
17585 }
17586
17587 return enemy::animate(index);
17588 }
17589
17590 void esManhandla::draw(BITMAP *dest)
17591 {
17592 tile=o_tile;
17593 int32_t fdiv = frate/4;
17594 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
17595 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
17596 efrate:((clk>=(frate>>1))?1:0);
17597
17598 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17599 {
17600 switch(misc&3)
17601 {
17602 case up:
17603 break;
17604
17605 case down:
17606 tile+=4;
17607 break;
17608
17609 case left:
17610 tile+=8;
17611 break;
17612
17613 case right:
17614 tile+=12;
17615 break;
17616 }
17617
17618 tile+=f2;
17619 }
17620 else
17621 {
17622 switch(misc&3)
17623 {
17624 case down:
17625 flip=2;
17626
17627 [[fallthrough]];
17628 case up:
17629 tile=(clk3)?188:189;
17630 break;
17631
17632 case right:
17633 flip=1;
17634 [[fallthrough]];
17635
17636 case left:
17637 tile=(clk3)?186:187;
17638 break;
17639 }
17640 }
17641
17642 enemy::draw(dest);
17643 }
17644
17645 eGleeok::eGleeok(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk) //enemy((zfix)120,(zfix)48,Id,Clk)
17646 {
17647 if ( !(editorflags & ENEMY_FLAG5) )
17648 {
17649 x = 120;
17650 y = 48;
17651 }
17652 else
17653 {
17654 if ( !(editorflags & ENEMY_FLAG6) )
17655 {
17656 x = X; y = Y;
17657 }
17658 else
17659 {
17660 x = X+8; y = Y;
17661 }
17662 }
17663 hzsz = 32; // can't be jumped.
17664 flameclk=0;
17665 misc=clk; // total head count
17666 clk3=clk; // live head count
17667 clk=0;
17668 clk2=60; // fire ball clock
17669 // hp=(guysbuf[eGLEEOK2+(misc-2)].misc2)*(misc-1)*game->get_hero_dmgmult()+guysbuf[eGLEEOK2+(misc-2)].hp;
17670 hp=(guysbuf[id&0xFFF].misc2)*(misc-1)*game->get_hero_dmgmult()+guysbuf[id&0xFFF].hp;
17671 dir = down;
17672 hxofs=4;
17673 hxsz=8;
17674 // frate=17*4;
17675 fading=fade_blue_poof;
17676 //nets+5420;
17677 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17678 {
17679 /*
17680 necktile=o_tile+8;
17681 if (dmisc3)
17682 {
17683 necktile+=8;
17684 }
17685 */
17686 necktile=o_tile+dmisc6;
17687 }
17688 else
17689 {
17690 necktile=s_tile;
17691 }
17692 }
17693
17694 bool eGleeok::animate(int32_t index)
17695 {
17696 if(switch_hooked) return enemy::animate(index);
17697 if(dying)
17698 return Dead(index);
17699
17700 if(clk==0)
17701 {
17702 removearmos(x,y,ffcactivated);
17703 }
17704
17705 // Check if a head was killed somehow...
17706 if(index+1+clk3>=guys.Count())
17707 clk3=guys.Count()-index-1;
17708 if(index+1+misc>=guys.Count())
17709 misc=guys.Count()-index-1;
17710
17711 //fix for the "kill all enemies" item
17712 if(hp==-1000)
17713 {
17714 for(int32_t i=0; i<clk3; ++i)
17715 {
17716 // I haven't seen this fail, but it seems like it ought to be
17717 // possible, so I'm checking for it. - Saf
17718 if((((enemy*)guys.spr(index+i+1))->id&0xFFF)!=(id&0xFFF))
17719 break;
17720 ((enemy*)guys.spr(index+i+1))->hp=1; // re-animate each head,
17721 ((enemy*)guys.spr(index+i+1))->misc = -1; // disconnect it,
17722 ((enemy*)guys.spr(index+i+1))->animate(index+i+1); // let it animate one frame,
17723 ((enemy*)guys.spr(index+i+1))->hp=-1000; // and kill it for good
17724 }
17725
17726 clk3=0;
17727
17728 for(int32_t i=0; i<misc; i++)
17729 {
17730 if((((enemy*)guys.spr(index+i+1))->id&0xFFF)!=(id&0xFFF))
17731 break;
17732 ((enemy*)guys.spr(index+i+1))->misc = -2; // give the signal to disappear
17733 }
17734 }
17735
17736 for(int32_t i=0; i<clk3; i++)
17737 {
17738 enemy *head = ((enemy*)guys.spr(index+i+1));
17739 head->dummy_int[1]=necktile;
17740 head->parent_script_UID = this->script_UID;
17741
17742 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17743 {
17744 head->dummy_int[2]=o_tile+dmisc8; //connected head tile
17745 head->dummy_int[3]=o_tile+dmisc9; //flying head tile
17746 }
17747 else
17748 {
17749 head->dummy_int[2]=necktile+1; //connected head tile
17750 head->dummy_int[3]=necktile+2; //flying head tile
17751 }
17752
17753 head->dmisc5=dmisc5; //neck segments
17754
17755 /*
17756 if (dmisc3)
17757 {
17758 head->dummy_bool[0]=true;
17759 }
17760 */
17761 if(head->hclk)
17762 {
17763 if(hclk==0)
17764 {
17765 hp -= 1000 - head->hp;
17766 hclk = 33;
17767
17768 if(hitsfx>0) sfx(hitsfx,pan(int32_t(head->x)));
17769
17770 sfx(WAV_EHIT,pan(int32_t(head->x)));
17771 }
17772
17773 head->hclk = 0;
17774 }
17775
17776 // Must be set in case of naughty ZScripts
17777 head->hp = 1000;
17778 }
17779
17780 if(hp<=(guysbuf[id&0xFFF].misc2)*(clk3-1)*game->get_hero_dmgmult())
17781 {
17782 ((enemy*)guys.spr(index+clk3))->misc = -1; // give signal to fly off
17783 hp=(guysbuf[id&0xFFF].misc2)*(--clk3)*game->get_hero_dmgmult();
17784 }
17785
17786 if(!dmisc3)
17787 {
17788 if(++clk2>72 && !(zc_oldrand()&3))
17789 {
17790 int32_t i=zc_oldrand()%misc;
17791 enemy *head = ((enemy*)guys.spr(index+i+1));
17792 addEwpn(head->x,head->y,head->z,wpn,3,wdp,dir,getUID(), 0, head->fakez);
17793 sfx(wpnsfx(wpn),pan(int32_t(x)));
17794 clk2=0;
17795 }
17796 }
17797 else
17798 {
17799 if(++clk2>100 && !(zc_oldrand()&3))
17800 {
17801 enemy *head = ((enemy*)guys.spr(zc_oldrand()%misc+index+1));
17802 head->timer=zc_oldrand()%50+50;
17803 clk2=0;
17804 }
17805 }
17806
17807 if((hp<=0 && !immortal))
17808 {
17809 for(int32_t i=0; i<misc; i++)
17810 ((enemy*)guys.spr(index+i+1))->misc = -2; // give the signal to disappear
17811
17812 if(flags&guy_neverret) never_return(index);
17813 }
17814
17815 return enemy::animate(index);
17816 }
17817
17818 int32_t eGleeok::takehit(weapon*)
17819 {
17820 return 0;
17821 }
17822
17823 void eGleeok::draw(BITMAP *dest)
17824 {
17825 tile=o_tile;
17826
17827 if(dying)
17828 {
17829 enemy::draw(dest);
17830 return;
17831 }
17832
17833 int32_t f=clk/17;
17834
17835 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17836 {
17837 // body
17838 xofs=-8;
17839 yofs=32;
17840
17841 switch(f)
17842
17843 {
17844 case 0:
17845 tile+=0;
17846 break;
17847
17848 case 1:
17849 tile+=2;
17850 break;
17851
17852 case 2:
17853 tile+=4;
17854 break;
17855
17856 default:
17857 tile+=6;
17858 break;
17859 }
17860 }
17861 else
17862 {
17863 // body
17864 xofs=-8;
17865 yofs=32;
17866
17867 switch(f)
17868 {
17869 case 0:
17870 tile+=0;
17871 break;
17872
17873 case 2:
17874 tile+=4;
17875 break;
17876
17877 default:
17878 tile+=2;
17879 break;
17880 }
17881 }
17882
17883 enemy::drawblock(dest,15);
17884 }
17885
17886 void eGleeok::draw2(BITMAP *dest)
17887 {
17888 // the neck stub
17889 tile=necktile;
17890 xofs=0;
17891 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
17892
17893 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17894 {
17895 tile+=((clk&24)>>3);
17896 }
17897
17898 if(hp > 0 && !dont_draw())
17899 {
17900 if((tmpscr->flags3&fINVISROOM)&& !(current_item(itype_amulet)))
17901 sprite::drawcloaked(dest);
17902 else
17903 sprite::draw(dest);
17904 }
17905 }
17906
17907 esGleeok::esGleeok(zfix X,zfix Y,int32_t Id,int32_t Clk, sprite * prnt) : enemy(X,Y,Id,Clk), parent(prnt)
17908 {
17909 xoffset=0;
17910 yoffset=(zfix)((dmisc5*4+2));
17911 // dummy_bool[0]=false;
17912 timer=0;
17913 /* fixing */
17914 hp=1000;
17915 step=1;
17916 item_set=0;
17917 //x=120; y=70;
17918 x = xoffset+parent->x;
17919 y = yoffset+parent->y;
17920 hxofs=4;
17921 hxsz=8;
17922 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
17923 clk2=clk; // how int32_t to wait before moving first time
17924 clk=0;
17925 mainguy=count_enemy=false;
17926 dir=zc_oldrand();
17927 clk3=((dir&2)>>1)+2; // left or right
17928 dir&=1; // up or down
17929 dmisc5=vbound(dmisc5,1,255);
17930 isCore = false;
17931 parentCore = parent->getUID();
17932 for(int32_t i=0; i<dmisc5; i++)
17933 {
17934 nxoffset[i] = 0;
17935 nyoffset[i] = 0;
17936 nx[i] = ((((i*(int32_t)x) + (dmisc5-i)*((int32_t)parent->x))) /dmisc5);
17937 ny[i] = ((((i*(int32_t)y) + (dmisc5-i)*((int32_t)parent->y))) /dmisc5);
17938 }
17939
17940 necktile=0;
17941 //TODO compatibility? -DD
17942 /*
17943 for(int32_t i=0; i<4; i++)
17944 {
17945 nx[i]=124;
17946 ny[i]=i*6+48;
17947 }*/
17948 bgsfx=-1;
17949 //no need for deadsfx
17950 }
17951
17952 bool esGleeok::animate(int32_t index)
17953 {
17954 if(switch_hooked) return enemy::animate(index);
17955 // don't call removearmos() - it's a segment.
17956
17957 dmisc5=vbound(dmisc5,1,255);
17958
17959 if(misc == 0)
17960 {
17961 x = (xoffset+parent->x);
17962 y = (yoffset+parent->y);
17963
17964 for(int32_t i=0; i<dmisc5; i++)
17965 {
17966 nx[i] = ((((i*(int32_t)x) + (dmisc5-i)*((int32_t)parent->x))) /dmisc5) + 3 + nxoffset[i];
17967 ny[i] = ((((i*(int32_t)y) + (dmisc5-i)*((int32_t)parent->y))) /dmisc5) + nyoffset[i];
17968 }
17969 }
17970
17971 // set up the head tiles
17972 // headtile=nets+5588; //5580, actually. must adjust for direction later on
17973 /*
17974 if (dummy_bool[0]) //if this is a flame gleeok
17975 {
17976 headtile+=180;
17977 }
17978 */
17979 headtile=dummy_int[2]; //5580, actually. must adjust for direction later on
17980 flyingheadtile=dummy_int[3];
17981
17982 // set up the neck tiles
17983 necktile=dummy_int[1];
17984
17985 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17986 {
17987 necktile+=((clk&24)>>3);
17988 }
17989
17990 /*
17991 else
17992 {
17993 necktile=145;
17994 }
17995 */
17996 // ?((dummy_bool[0])?(nets+4052+(16+((clk&24)>>3))):(nets+4040+(8+((clk&24)>>3)))):145)
17997
17998 switch(misc)
17999 {
18000 case 0: // live head
18001 // set up the attached head tiles
18002 tile=headtile;
18003
18004 if(get_bit(quest_rules,qr_NEWENEMYTILES))
18005 {
18006 tile+=((clk&24)>>3);
18007 /*
18008 if (dummy_bool[0]) {
18009 tile+=1561;
18010 }
18011 */
18012 }
18013
18014 /*
18015 else
18016 {
18017 tile=146;
18018 }
18019 */
18020 if(++clk2>=0 && !(clk2&3))
18021 {
18022 if(y<= (int32_t)parent->y + 8) dir=down;
18023
18024 if(y>= (int32_t)parent->y + dmisc5*8) dir = up;
18025
18026 if(y<= (int32_t)parent->y + 10 && !(zc_oldrand()&31))
18027 {
18028 dir^=1;
18029 }
18030
18031 zfix tempx = x;
18032 zfix tempy = y;
18033
18034 sprite::move(step);
18035 xoffset += (x-tempx);
18036 yoffset += (y-tempy);
18037
18038 if(clk2>=4)
18039 {
18040 clk3^=1;
18041 clk2=-4;
18042 }
18043 else
18044 {
18045 if(x <= (int32_t)parent->x-(dmisc5*6))
18046 {
18047 clk3=right;
18048 }
18049
18050 if(x >= (int32_t)parent->x+(dmisc5*6))
18051 {
18052 clk3=left;
18053 }
18054
18055 if(y <= (int32_t)parent->y+(dmisc5*6) && !(zc_oldrand()&15))
18056 {
18057 clk3^=1; // x jig
18058 }
18059 else
18060 {
18061 if(y<=(int32_t)parent->y+(dmisc5*4) && !(zc_oldrand()&31))
18062 {
18063 clk3^=1; // x switch back
18064 }
18065
18066 clk2=-4;
18067 }
18068 }
18069
18070 zc_swap(dir,clk3);
18071 tempx = x;
18072 tempy = y;
18073 sprite::move(step);
18074 xoffset += (x-tempx);
18075 yoffset += (y-tempy);
18076 zc_swap(dir,clk3);
18077
18078 for(int32_t i=1; i<dmisc5; i++)
18079 {
18080 nxoffset[i] = (zc_oldrand()%3);
18081 nyoffset[i] = (zc_oldrand()%3);
18082 }
18083 }
18084
18085 break;
18086
18087 case 1: // flying head
18088 if(clk>=0)
18089
18090 {
18091 variable_walk_8(rate,homing,hrate,spw_floater);
18092 }
18093
18094 break;
18095
18096 // the following are messages sent from the main guy...
18097 case -1: // got chopped off
18098 {
18099 misc=1;
18100 superman=1;
18101 hxofs=xofs=0;
18102 hxsz=16;
18103 cs=8;
18104 clk=-24;
18105 clk2=40;
18106 dir=(zc_oldrand()&7)+8;
18107 step=8.0/9.0;
18108 }
18109 break;
18110
18111 case -2: // the big guy is dead
18112 return true;
18113 }
18114
18115 if(timer)
18116 {
18117 if(!(timer%8))
18118 {
18119 FireBreath(true);
18120 }
18121
18122 --timer;
18123 }
18124
18125 return enemy::animate(index);
18126 }
18127
18128 int32_t esGleeok::takehit(weapon *w)
18129 {
18130 if ((editorflags & ENEMY_FLAG7) && misc == 1)
18131 {
18132 int32_t wpnId = w->id;
18133
18134 if(dying)
18135 return 0;
18136
18137 switch(wpnId)
18138 {
18139 case wLitBomb:
18140 case wLitSBomb:
18141 case wBait:
18142 case wWhistle:
18143 case wFire:
18144 case wWind:
18145 case wSSparkle:
18146 case wFSparkle:
18147 case wPhantom:
18148 return 0;
18149
18150 case wHookshot:
18151 case wBrang:
18152 case wBeam:
18153 case wArrow:
18154 case wMagic:
18155 case wBomb:
18156 case wSBomb:
18157 sfx(WAV_CHINK,pan(int32_t(x)));
18158 break;
18159 default:
18160 break;
18161 }
18162
18163 return 1;
18164 }
18165 else
18166 {
18167 int32_t ret = enemy::takehit(w);
18168
18169 if(ret==-1)
18170 return 2; // force it to wait a frame before checking sword attacks again
18171
18172 return ret;
18173 }
18174 }
18175
18176 void esGleeok::draw(BITMAP *dest)
18177 {
18178 dmisc5=vbound(dmisc5,1,255);
18179
18180 switch(misc)
18181 {
18182 case 0: //neck
18183 if(!dont_draw())
18184 {
18185 for(int32_t i=1; i<dmisc5; i++) //draw the neck
18186 {
18187 if(get_bit(quest_rules,qr_NEWENEMYTILES))
18188 {
18189 if((tmpscr->flags3&fINVISROOM)&& !(current_item(itype_amulet)))
18190 overtilecloaked16(dest,necktile+(i*dmisc7),nx[i]-4,ny[i]+playing_field_offset,0);
18191 else
18192 overtile16(dest,necktile+(i*dmisc7),nx[i]-4,ny[i]+playing_field_offset,cs,0);
18193 }
18194 else
18195 {
18196 if((tmpscr->flags3&fINVISROOM)&& !(current_item(itype_amulet)))
18197 overtilecloaked16(dest,necktile,nx[i]-4,ny[i]+playing_field_offset,0);
18198 else
18199 overtile16(dest,necktile,nx[i]-4,ny[i]+playing_field_offset,cs,0);
18200 }
18201 }
18202 }
18203
18204 break;
18205
18206 case 1: //flying head
18207 tile=flyingheadtile;
18208
18209 if(get_bit(quest_rules,qr_NEWENEMYTILES))
18210 {
18211 tile+=((clk&24)>>3);
18212 break;
18213 }
18214
18215 /*
18216 else
18217 {
18218 tile=(clk&1)?147:148;
18219 break;
18220 }
18221 */
18222 }
18223 }
18224
18225 void esGleeok::draw2(BITMAP *dest)
18226 {
18227 enemy::draw(dest);
18228 }
18229
18230 ePatra::ePatra(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)// enemy((zfix)128,(zfix)48,Id,Clk)
18231 {
18232 if ( !(editorflags & ENEMY_FLAG5) )
18233 {
18234 x = 128;
18235 y = 48;
18236 }
18237 else { x = X; y = Y; }
18238 adjusted=false;
18239 dir=(zc_oldrand()&7)+8;
18240 //step=0.25;
18241 flycnt=dmisc1;
18242 flycnt2=dmisc2;
18243 loopcnt=0;
18244 clk4 = 0;
18245 clk5 = 0;
18246 clk6 = 0;
18247 clk7 = 0;
18248 if(dmisc6<int16_t(1))dmisc6=1; // ratio cannot be 0!
18249 SIZEflags = d->SIZEflags;
18250 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
18251 else if (dmisc10 == 1) { txsz = 2; extend = 3; }
18252 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
18253 // al_trace("Enemy txsz:%i\n", txsz);
18254 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = tysz; if ( tysz > 1 ) extend = 3; }
18255 else if (dmisc10 == 1) { tysz = 2; extend = 3; }
18256 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = hxsz;
18257 else if (dmisc10 == 1) hxsz = 32;
18258 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = hysz;
18259 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = hzsz;
18260 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = hxofs;
18261 else if (dmisc10 == 1) hxofs = -8;
18262 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = hyofs;
18263 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
18264 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)xofs;
18265 else if (dmisc10 == 1) xofs = -8;
18266 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
18267 {
18268 yofs = (int32_t)yofs; //This seems to be setting to +48 or something with any value set?! -Z
18269 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
18270 }
18271 else if (dmisc10 == 1) yofs = (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset)-8;
18272 if (editorflags & ENEMY_FLAG8) misc = 1;
18273
18274 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
18275
18276 if (dmisc29 == 0)
18277 {
18278 if(!dmisc4)
18279 {
18280 if (dmisc10) dmisc29 = (90 / 3);
18281 else dmisc29 = (84 / 3);
18282 }
18283 else
18284 {
18285 if (dmisc10) dmisc29 = (90 / 2);
18286 else dmisc29 = (84 / 2);
18287 }
18288 }
18289 if (dmisc30 == 0)
18290 {
18291 if(!dmisc4)
18292 {
18293 if (dmisc10) dmisc30 = (90 / 3)*0.5;
18294 else dmisc30 = (84 / 3)*0.5;
18295 }
18296 else
18297 {
18298 if (dmisc10) dmisc30 = (90 / 2)*0.5;
18299 else dmisc30 = (84 / 2)*0.5;
18300 }
18301 }
18302 if (dmisc31 == 0)
18303 {
18304 if(!dmisc4)
18305 {
18306 if (dmisc10) dmisc31 = (90 / 3)*2;
18307 else dmisc31 = (84 / 3)*2;
18308 }
18309 else
18310 {
18311 if (dmisc10) dmisc31 = (90 / 2)*0.5;
18312 else dmisc31 = (84 / 2)*0.5;
18313 }
18314 }
18315 if (dmisc32 == 0)
18316 {
18317 if(!dmisc4)
18318 {
18319 if (dmisc10) dmisc32 = (90 / 3);
18320 else dmisc32 = (84 / 3);
18321 }
18322 else
18323 {
18324 if (dmisc10) dmisc32 = (90 / 2)*0.25;
18325 else dmisc32 = (84 / 2)*0.25;
18326 }
18327 }
18328 }
18329
18330 bool ePatra::animate(int32_t index)
18331 {
18332 if(switch_hooked) return enemy::animate(index);
18333 if(dying)
18334 {
18335 for(int32_t i=index+1; i<index+flycnt+flycnt2+1; i++)
18336 {
18337 ((enemy*)guys.spr(i))->hp = -1000;
18338 }
18339
18340 return Dead(index);
18341 }
18342
18343 double basesize = 84;
18344 if (dmisc10) basesize = 90;
18345 double halfsize = basesize / 2;
18346 double quartersize = halfsize / 2;
18347 double twothirdsize = (basesize / 3)*2;
18348 double onethirdsize = (basesize / 3);
18349
18350
18351 if(clk==0)
18352 {
18353 removearmos(x,y,ffcactivated);
18354 }
18355
18356 if ((clk4 <=0 || clk4%2) && (clk7 <= 0 || clk6 <= -16))
18357 {
18358 if (!dmisc22 || loopcnt == 0 || (dmisc22 == 1 && loopcnt < 0)) variable_walk_8(rate,homing,hrate,spw_floater);
18359 if (loopcnt < 0) ++clk2;
18360 if(++clk2>basesize)
18361 {
18362 clk2=0;
18363 if ((!dmisc26 || (dmisc26 == 1 && flycnt) || (dmisc26 == 2 && !flycnt)) && (!(editorflags & ENEMY_FLAG10) || flycnt || flycnt2))
18364 {
18365 if(loopcnt > 0)
18366 --loopcnt;
18367 else if (loopcnt == 0)
18368 {
18369 if((misc%dmisc6)==0)
18370 {
18371 if (dmisc21 > 0) loopcnt=-dmisc21;
18372 else loopcnt=dmisc7;
18373 }
18374 }
18375 else if (loopcnt == -1) loopcnt=dmisc7;
18376 else ++loopcnt;
18377
18378 if (!(editorflags & ENEMY_FLAG9) || loopcnt == 0) ++misc;
18379 }
18380 else
18381 {
18382 loopcnt = 0;
18383 misc = 1;
18384 }
18385 }
18386 }
18387 if (clk4 > 0) --clk4;
18388
18389 double size=1;
18390
18391 if (clk6 < 0)
18392 {
18393 if (dmisc5 == 1 || dmisc5 == 3)
18394 {
18395 if (get_bit(quest_rules,qr_NEWENEMYTILES))
18396 {
18397 if (clk7 <= 0 || clk6 != -16) ++clk6;
18398 if (clk6 == 0) o_tile=d->e_tile;
18399 else
18400 {
18401 if (clk6 >= -16) o_tile=d->e_tile + (IsBigAnim() ? 320 : 80);
18402 else o_tile=d->e_tile + (IsBigAnim() ? 160 : 40);
18403 }
18404 }
18405 else clk6 = 0;
18406 }
18407 }
18408 else if (dmisc19) ++clk6;
18409 if (clk5 < 0) ++clk5;
18410 else if (dmisc19) ++clk5;
18411
18412 if (clk7 > 0 && clk6 >= -16) --clk7;
18413 if (clk6 > 0) clk7 = 0;
18414
18415 for(int32_t i=index+1; i<index+flycnt+1; i++)
18416 {
18417 //outside ring
18418 if(!adjusted)
18419 {
18420 if(get_bit(quest_rules,qr_NEWENEMYTILES))
18421 {
18422 ((enemy*)guys.spr(i))->o_tile=d->e_tile+dmisc8;
18423 enemy *s = ((enemy*)guys.spr(i));
18424 s->parent_script_UID = this->script_UID;
18425 }
18426 else
18427 {
18428 ((enemy*)guys.spr(i))->o_tile=o_tile+1;
18429 enemy *s = ((enemy*)guys.spr(i));
18430 s->parent_script_UID = this->script_UID;
18431 }
18432
18433 ((enemy*)guys.spr(i))->cs=dmisc9;
18434 ((enemy*)guys.spr(i))->hp=dmisc3;
18435 }
18436
18437 if(((enemy*)guys.spr(i))->hp <= 0)
18438 {
18439 for(int32_t j=i; j<index+flycnt+flycnt2; j++)
18440 {
18441 guys.swap(j,j+1);
18442 }
18443
18444 if (--flycnt == 0 && dmisc23 != 0) step += zslongToFix(dmisc23*100);
18445 }
18446 else
18447 {
18448 int32_t pos2 = ((enemy*)guys.spr(i))->misc;
18449 double a2 = (clk2-pos2*(double)basesize/(dmisc1 == 0 ? 1 : dmisc1))*PI/halfsize;
18450
18451 if(!dmisc4) //Big Ring
18452 {
18453 //maybe playing_field_offset here?
18454 if(loopcnt>0)
18455 {
18456 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc31) - zc::math::Sin(pos2*PI*2/(dmisc1 == 0 ? 1 : dmisc1))*((int64_t)abs(dmisc31)-abs(dmisc29));
18457 guys.spr(i)->y = -zc::math::Sin(a2+PI/2)*abs(dmisc31) + zc::math::Cos(pos2*PI*2/(dmisc1 == 0 ? 1 : dmisc1))*((int64_t)abs(dmisc31)-abs(dmisc29));
18458 }
18459 else
18460 {
18461 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc29);
18462 guys.spr(i)->y = -zc::math::Sin(a2+PI/2)*abs(dmisc29);
18463 }
18464
18465 temp_x=guys.spr(i)->x;
18466 temp_y=guys.spr(i)->y;
18467 }
18468 else //Oval
18469 {
18470 circle_x = zc::math::Cos(a2+PI/2)*abs(dmisc29);
18471 circle_y = -zc::math::Sin(a2+PI/2)*abs(dmisc29);
18472
18473 if(loopcnt>0)
18474 {
18475 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc29);
18476 guys.spr(i)->y = (-zc::math::Sin(a2+PI/2)-zc::math::Cos(pos2*PI*2/(dmisc1 == 0 ? 1 : dmisc1)))*abs(dmisc31);
18477 }
18478 else
18479 {
18480 guys.spr(i)->x = circle_x;
18481 guys.spr(i)->y = circle_y;
18482 }
18483
18484 temp_x=circle_x;
18485 temp_y=circle_y;
18486 }
18487
18488 double _MSVC2022_tmp1, _MSVC2022_tmp2;
18489 double ddir=atan2_MSVC2022_FIX(double(temp_y),double(temp_x));
18490
18491 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
18492 {
18493 guys.spr(i)->dir=l_down;
18494 }
18495 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
18496 {
18497 guys.spr(i)->dir=left;
18498 }
18499 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
18500 {
18501 guys.spr(i)->dir=l_up;
18502 }
18503 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
18504 {
18505 guys.spr(i)->dir=up;
18506 }
18507 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
18508 {
18509 guys.spr(i)->dir=r_up;
18510 }
18511 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
18512 {
18513 guys.spr(i)->dir=right;
18514 }
18515 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
18516 {
18517 guys.spr(i)->dir=r_down;
18518 }
18519 else
18520 {
18521 guys.spr(i)->dir=down;
18522 }
18523
18524 guys.spr(i)->x += x;
18525 guys.spr(i)->y += y;
18526 }
18527 }
18528
18529 if((wpn>wEnemyWeapons || (wpn >= wScript1 && wpn <= wScript10)) && (dmisc5==1 || dmisc5== 3) && (!dmisc25 || (dmisc25 == 1 && !flycnt && !flycnt2) || (dmisc25 == 2 && (flycnt || flycnt2)) || (dmisc25 == 3 && flycnt2 && !flycnt)))
18530 {
18531 int timeneeded = 48;
18532 int patbreath = (zc_oldrand()%50+50);
18533 if ((patbreath % 4) == 0) ++patbreath;
18534 if (dmisc28 == patratBREATH)
18535 {
18536 timeneeded = 48 + patbreath;
18537 }
18538 if (dmisc28 == patratSTREAM)
18539 {
18540 timeneeded = 48 + 96;
18541 }
18542 if (((((dmisc18 > 0 || ((editorflags & ENEMY_FLAG10) && !flycnt && !flycnt2)) && !(zc_oldrand() % zc_max(dmisc18, 1))) || //New 1/N chance
18543 (dmisc18 == 0 && !(zc_oldrand()&127)) //Old hardcoded firing chance
18544 || (dmisc18 == -1 && loopcnt > 0 && (clk2 == round(halfsize) && (!(editorflags & ENEMY_FLAG3) || !get_bit(quest_rules,qr_NEWENEMYTILES))
18545 || (clk4 == 10 && (editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES)))))
18546 && (clk6 >= 0) //if not in the middle of firing...
18547 && clk6 >= dmisc19) //if over the set cooldown between shots...
18548 && ((!(editorflags & ENEMY_FLAG7) || (loopcnt == 0 && (basesize*((int64_t)dmisc6 - (misc%dmisc6))) > timeneeded)) || dmisc18 == -1)) //And lastly, if not in danger of starting a loop during the attack.
18549 {
18550 switch(dmisc28)
18551 {
18552 case patratSTREAM:
18553 {
18554 clk7 = 97;
18555 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES)) clk6 = -48;
18556 else clk6 = 0;
18557 break;
18558 }
18559 case patratBREATH:
18560 {
18561 clk7 = patbreath;
18562 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES)) clk6 = -48;
18563 else clk6 = 0;
18564 break;
18565 }
18566 default:
18567 {
18568 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES))
18569 {
18570 clk6 = -48;
18571 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk6) + 16;
18572 }
18573 else
18574 {
18575 clk6 = 0;
18576 if (editorflags & ENEMY_FLAG6) clk4 = 16;
18577 FirePatraWeapon();
18578 }
18579 break;
18580 }
18581 } //ew->setAngle(atan2(double(HeroY()-y),double(HeroX()-x)));
18582 }
18583 if (clk6 < 0)
18584 {
18585 switch(dmisc28)
18586 {
18587 case patratSTREAM:
18588 {
18589 if (clk7 > 0 && (clk7 % 12) == 0) FirePatraWeapon();
18590 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk6) + 16;
18591 break;
18592 }
18593 case patratBREATH:
18594 {
18595 if (clk7 > 0 && (clk7 % 4) == 0) FirePatraWeapon();
18596 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk6) + 16;
18597 break;
18598 }
18599 default:
18600 {
18601 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES) && clk6 == -16)
18602 {
18603 FirePatraWeapon();
18604 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk6) + 16;
18605 }
18606 break;
18607 }
18608 }
18609 }
18610 }
18611
18612 size=.5;
18613 int randattempts = 0;
18614 int randeye = 0;
18615 if (flycnt2 > 0)
18616 {
18617 do
18618 {
18619 randeye = ((flycnt2 > 0) ? (zc_oldrand() % zc_max(1, flycnt2)) : 0);
18620 randeye += (index + flycnt + 1);
18621 ++randattempts;
18622 } while (((esPatra*)guys.spr(randeye))->clk5 < 0 && randattempts < 10);
18623 }
18624 bool dofire = false;
18625 if (dmisc20)
18626 {
18627 if ((dmisc18 > 0 && !(zc_oldrand() % zc_max(dmisc18, 1))) ||
18628 (dmisc18 == 0 && !(zc_oldrand()&127)) ||
18629 (dmisc18 == -1 && (loopcnt > 0 || dmisc20 == 4) && ((clk2 == round(halfsize) && (!(editorflags & ENEMY_FLAG3) || !get_bit(quest_rules,qr_NEWENEMYTILES)) && dmisc20 != 2 && dmisc20 != 4)
18630 || (clk2 == 10 && dmisc20 != 4 && ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES) || dmisc20 == 2))
18631 || ((((((misc%dmisc6) == 0 && (loopcnt == 0 && !dmisc21)) || loopcnt > 1 || loopcnt == -1) && clk2 <= 53 && clk2 >= 51 && (editorflags & ENEMY_FLAG3)) || (!(editorflags & ENEMY_FLAG3) && loopcnt > 0 && clk2 == 1)) && dmisc20 == 4))))
18632 {
18633 if (clk5 >= 0 || !(editorflags & ENEMY_FLAG3) || !get_bit(quest_rules,qr_NEWENEMYTILES))
18634 {
18635 if (clk5 >= dmisc19)
18636 {
18637 if ((!(editorflags & ENEMY_FLAG7) || (loopcnt == 0 &&
18638 (dmisc20 == 2 && (basesize*((int64_t)dmisc6 - (misc%dmisc6))) > ((int64_t)48 + (int64_t(12)*flycnt2))) ||
18639 (dmisc20 == 4 && (basesize*((int64_t)dmisc6 - (misc%dmisc6))) > ((int64_t)48 + 96)) ||
18640 (dmisc20 != 2 && dmisc20 != 4 && (basesize*((int64_t)dmisc6 - (misc%dmisc6))) > 48)))
18641 || dmisc18 == -1)
18642 dofire = true;
18643 }
18644 }
18645 }
18646 }
18647 if(flycnt2)
18648 {
18649 for(int32_t i=index+flycnt+1; i<index+flycnt+flycnt2+1; i++)//inner ring
18650 {
18651 if(!adjusted)
18652 {
18653 ((enemy*)guys.spr(i))->hp=12*game->get_hero_dmgmult();
18654
18655 if(get_bit(quest_rules,qr_NEWENEMYTILES))
18656 {
18657 if (get_bit(quest_rules,qr_PATRAS_USE_HARDCODED_OFFSETS))
18658 {
18659 switch(dmisc5)
18660 {
18661 // Center eye shoots projectiles; make room for its firing tiles
18662 case 1:
18663 case 3:
18664 ((enemy*)guys.spr(i))->o_tile=d->e_tile+120;
18665 break;
18666
18667 // Center eyes does not shoot; use tiles two rows below for inner eyes.
18668 default:
18669 case 2:
18670 ((enemy*)guys.spr(i))->o_tile=d->e_tile+40;
18671 break;
18672 }
18673 }
18674 else ((enemy*)guys.spr(i))->o_tile = d->s_tile;
18675 }
18676 else
18677 {
18678 ((enemy*)guys.spr(i))->o_tile=o_tile+1;
18679 }
18680
18681 ((enemy*)guys.spr(i))->cs=dmisc9;
18682 if (dmisc27) ((enemy*)guys.spr(i))->hp=dmisc27;
18683 }
18684
18685 if(flycnt>0)
18686 {
18687 ((enemy*)guys.spr(i))->superman=true;
18688 }
18689 else
18690 {
18691 ((enemy*)guys.spr(i))->superman=false;
18692 }
18693
18694 if(((enemy*)guys.spr(i))->hp <= 0)
18695 {
18696 for(int32_t j=i; j<index+flycnt+flycnt2; j++)
18697 {
18698 guys.swap(j,j+1);
18699 }
18700
18701 if (--flycnt2 == 0 && dmisc24 != 0) step += zslongToFix(dmisc24*100);
18702 }
18703 else
18704 {
18705 int32_t pos2 = ((enemy*)guys.spr(i))->misc;
18706 double a2 = ((clk2-pos2*basesize/(dmisc2==0 ? 1 : dmisc2))*PI/(halfsize));
18707
18708 if(dmisc4==0)
18709 {
18710 if(loopcnt>0)
18711 {
18712 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc32) - zc::math::Sin(pos2*PI*2/(dmisc2==0?1:dmisc2))*((int64_t)abs(dmisc32)-abs(dmisc30));
18713 guys.spr(i)->y = -zc::math::Sin(a2+PI/2)*abs(dmisc32) + zc::math::Cos(pos2*PI*2/(dmisc2==0?1:dmisc2))*((int64_t)abs(dmisc32)-abs(dmisc30));
18714 }
18715 else
18716 {
18717 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc30);
18718 guys.spr(i)->y = -zc::math::Sin(a2+PI/2)*abs(dmisc30);
18719 }
18720
18721 temp_x=guys.spr(i)->x;
18722 temp_y=guys.spr(i)->y;
18723 }
18724 else
18725 {
18726 circle_x = zc::math::Cos(a2+PI/2)*abs(dmisc30);
18727 circle_y = -zc::math::Sin(a2+PI/2)*abs(dmisc30);
18728
18729 if(loopcnt>0)
18730 {
18731 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc30);
18732 guys.spr(i)->y = (-zc::math::Sin(a2+PI/2)-zc::math::Cos(pos2*PI*2/(dmisc2 == 0 ? 1 : dmisc2)))*abs(dmisc32);
18733 }
18734 else
18735 {
18736 guys.spr(i)->x = circle_x;
18737 guys.spr(i)->y = circle_y;
18738 }
18739
18740 temp_x=circle_x;
18741 temp_y=circle_y;
18742 }
18743
18744 double _MSVC2022_tmp1, _MSVC2022_tmp2;
18745 double ddir=atan2_MSVC2022_FIX(double(temp_y),double(temp_x));
18746
18747 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
18748 {
18749 guys.spr(i)->dir=l_down;
18750 }
18751 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
18752 {
18753 guys.spr(i)->dir=left;
18754 }
18755 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
18756 {
18757 guys.spr(i)->dir=l_up;
18758 }
18759 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
18760 {
18761 guys.spr(i)->dir=up;
18762 }
18763 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
18764 {
18765 guys.spr(i)->dir=r_up;
18766 }
18767 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
18768 {
18769 guys.spr(i)->dir=right;
18770 }
18771 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
18772 {
18773 guys.spr(i)->dir=r_down;
18774 }
18775 else
18776 {
18777 guys.spr(i)->dir=down;
18778 }
18779
18780 guys.spr(i)->x += x;
18781 guys.spr(i)->y = y-guys.spr(i)->y;
18782
18783 if((wpn>wEnemyWeapons || (wpn >= wScript1 && wpn <= wScript10)) && (dmisc5==2 || dmisc5== 3))
18784 {
18785 /*
18786 if(!(zc_oldrand()&127))
18787 {
18788 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID());
18789 sfx(wpnsfx(wpn),pan(int32_t(x)));
18790 }
18791 */
18792 if (((esPatra*)guys.spr(i))->clk5 < 0 && (editorflags & ENEMY_FLAG3))
18793 {
18794 if (((esPatra*)guys.spr(i))->clk4 <= 0 || ((esPatra*)guys.spr(i))->clk5 != -16) ++((esPatra*)guys.spr(i))->clk5;
18795 if (get_bit(quest_rules,qr_PATRAS_USE_HARDCODED_OFFSETS))
18796 {
18797 if (dmisc5 == 3)
18798 {
18799 if (((esPatra*)guys.spr(i))->clk5 >= 0) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+120;
18800 else if (((esPatra*)guys.spr(i))->clk5 >= -16) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+200;
18801 else if (((esPatra*)guys.spr(i))->clk5 >= -48) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+160;
18802 else ((esPatra*)guys.spr(i))->o_tile=d->e_tile+120;
18803 }
18804 else
18805 {
18806 if (((esPatra*)guys.spr(i))->clk5 >= 0) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+40;
18807 else if (((esPatra*)guys.spr(i))->clk5 >= -16) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+120;
18808 else if (((esPatra*)guys.spr(i))->clk5 >= -48) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+80;
18809 else ((esPatra*)guys.spr(i))->o_tile=d->e_tile+40;
18810 }
18811 }
18812 else
18813 {
18814 if (((esPatra*)guys.spr(i))->clk5 >= 0) ((esPatra*)guys.spr(i))->o_tile=d->s_tile;
18815 else if (((esPatra*)guys.spr(i))->clk5 >= -16) ((esPatra*)guys.spr(i))->o_tile=d->s_tile+80;
18816 else if (((esPatra*)guys.spr(i))->clk5 >= -48) ((esPatra*)guys.spr(i))->o_tile=d->s_tile+40;
18817 else ((esPatra*)guys.spr(i))->o_tile=d->s_tile;
18818 }
18819 }
18820 else if ((dmisc19 || ((esPatra*)guys.spr(i))->clk5) && (((esPatra*)guys.spr(i))->clk4 <= 0 || ((esPatra*)guys.spr(i))->clk5 != -16)) ++((esPatra*)guys.spr(i))->clk5;
18821 if (((esPatra*)guys.spr(i))->clk4 > 0) --((esPatra*)guys.spr(i))->clk4;
18822 if (!dmisc25 || (dmisc25 == 1 && !((enemy*)guys.spr(i))->superman) || ((dmisc25 == 2 || dmisc25 == 3) && ((enemy*)guys.spr(i))->superman))
18823 {
18824 switch(dmisc20) //Patra Attack Patterns
18825 {
18826 case 4: //Single one rapidfires
18827 {
18828 if (dofire && i == randeye)
18829 {
18830 ((esPatra*)guys.spr(i))->clk5 = -16;
18831 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES)) ((esPatra*)guys.spr(i))->clk5 = -48;
18832 ((esPatra*)guys.spr(i))->clk4 = 96;
18833 clk5 = -3;
18834 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk5) + 16;
18835 }
18836 if (((esPatra*)guys.spr(i))->clk5 == -16 && (((esPatra*)guys.spr(i))->clk4 % 12) == 0)
18837 {
18838 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18839 sfx(wpnsfx(wpn),pan(int32_t(x)));
18840 }
18841 break;
18842 }
18843 case 3: //Ring
18844 {
18845 if (dofire)
18846 {
18847 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES))
18848 {
18849 ((esPatra*)guys.spr(i))->clk5 = -48;
18850 clk5 = -48;
18851 if (editorflags & ENEMY_FLAG6) clk4 = 64;
18852 }
18853 else
18854 {
18855 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18856 sfx(wpnsfx(wpn),pan(int32_t(x)));
18857 int32_t m=Ewpns.Count()-1;
18858 weapon *ew = (weapon*)(Ewpns.spr(m));
18859
18860 ew->setAngle(atan2(double(HeroY()-y),double(HeroX()-x)));
18861 ((esPatra*)guys.spr(i))->clk5 = 0;
18862 clk5 = 0;
18863 if (editorflags & ENEMY_FLAG6) clk4 = 16;
18864 }
18865 }
18866 if (((esPatra*)guys.spr(i))->clk5 == -16)
18867 {
18868 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18869 sfx(wpnsfx(wpn),pan(int32_t(x)));
18870 int32_t m=Ewpns.Count()-1;
18871 weapon *ew = (weapon*)(Ewpns.spr(m));
18872
18873 ew->setAngle(atan2(double(HeroY()-y),double(HeroX()-x)));
18874 }
18875 break;
18876 }
18877 case 2: //one after another
18878 {
18879 if (dofire)
18880 {
18881 ((esPatra*)guys.spr(i))->clk5 = -48 - (12*(i-(index+flycnt+1)));
18882 clk5 = -48 - (12*flycnt2);
18883 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk5) + 16;
18884 }
18885 if (((esPatra*)guys.spr(i))->clk5 == -16)
18886 {
18887 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18888 sfx(wpnsfx(wpn),pan(int32_t(x)));
18889 }
18890 break;
18891 }
18892 case 1: //random one eye
18893 {
18894 if (dofire && i == randeye)
18895 {
18896 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES))
18897 {
18898 ((esPatra*)guys.spr(i))->clk5 = -48;
18899 clk5 = -48;
18900 if (editorflags & ENEMY_FLAG6) clk4 = 64;
18901 }
18902 else
18903 {
18904 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18905 sfx(wpnsfx(wpn),pan(int32_t(x)));
18906 ((esPatra*)guys.spr(i))->clk5 = 0;
18907 clk5 = 0;
18908 if (editorflags & ENEMY_FLAG6) clk4 = 16;
18909 }
18910 }
18911 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES) && ((esPatra*)guys.spr(i))->clk5 == -16)
18912 {
18913 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18914 sfx(wpnsfx(wpn),pan(int32_t(x)));
18915 }
18916 break;
18917 }
18918 default: //old behavior, all eyes can fire any time
18919 {
18920 if ((((dmisc18 && !(zc_oldrand() % zc_max(dmisc18, 1))) ||
18921 (!dmisc18 && !(zc_oldrand()&127))) && (((esPatra*)guys.spr(i))->clk5 >= 0 || !(editorflags & ENEMY_FLAG3) || !get_bit(quest_rules,qr_NEWENEMYTILES))
18922 && ((esPatra*)guys.spr(i))->clk5 >= dmisc19) && (!(editorflags & ENEMY_FLAG7) || (loopcnt == 0 &&
18923 (dmisc20 != 2 && (basesize*((int64_t)dmisc6 - (misc%dmisc6))) > 48))))
18924 {
18925 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES))
18926 {
18927 ((esPatra*)guys.spr(i))->clk5 = -48;
18928 if (editorflags & ENEMY_FLAG6) clk4 = 64;
18929 }
18930 else
18931 {
18932 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, fakez);
18933 sfx(wpnsfx(wpn),pan(int32_t(x)));
18934 ((esPatra*)guys.spr(i))->clk5 = 0;
18935 if (editorflags & ENEMY_FLAG6) clk4 = 16;
18936 }
18937 }
18938 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES) && ((esPatra*)guys.spr(i))->clk5 == -16)
18939 {
18940 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, fakez);
18941 sfx(wpnsfx(wpn),pan(int32_t(x)));
18942 }
18943 break;
18944 }
18945 }
18946 }
18947 }
18948
18949 }
18950 }
18951 }
18952
18953 adjusted=true;
18954 return enemy::animate(index);
18955 }
18956
18957 void ePatra::FirePatraWeapon()
18958 { //.707
18959 int32_t xoff = 0;
18960 int32_t yoff = 0;
18961 if ( SIZEflags&guyflagOVERRIDE_HIT_WIDTH )
18962 {
18963 xoff += (hxsz/2)-8;
18964 //Z_scripterrlog("width flag enabled. xoff = %d\n", xoff);
18965 }
18966 if ( SIZEflags&guyflagOVERRIDE_HIT_HEIGHT )
18967 {
18968 yoff += (hysz/2)-8;
18969 //Z_scripterrlog("width flag enabled. yoff = %d\n", yoff);
18970 }
18971 sfx(wpnsfx(wpn),pan(int32_t(x)));
18972 switch (dmisc28)
18973 {
18974 case patrat8SHOT: //Fire Wizzrobe
18975 case patrat4SHOTDIAG:
18976 case patrat4SHOTRAND:
18977 if (dmisc28 != patrat4SHOTRAND || (zc_oldrand()%2)) //if it's the 4 shot rand type, only let it through half the time. Break is within so it doesn't do both, but if it skips this one it'll always do the other one.
18978 {
18979 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,l_up,-1, getUID(),false));
18980 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
18981 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
18982 if (wpn != ewFlame && wpn != ewFlame2) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= .707; //Fire already does this internall for asome bizarre reason.
18983
18984 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,l_down,-1, getUID(),false));
18985 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
18986 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
18987 if (wpn != ewFlame && wpn != ewFlame2) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= .707; //Fire already does this internall for asome bizarre reason.
18988
18989 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,r_up,-1, getUID(),false));
18990 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
18991 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
18992 if (wpn != ewFlame && wpn != ewFlame2) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= .707; //Fire already does this internall for asome bizarre reason.
18993
18994 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,r_down,-1, getUID(),false));
18995 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
18996 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
18997 if (wpn != ewFlame && wpn != ewFlame2) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= .707; //Fire already does this internall for asome bizarre reason.
18998
18999 if (dmisc28 == patrat4SHOTDIAG || dmisc28 == patrat4SHOTRAND) break;
19000 }
19001
19002 [[fallthrough]];
19003 case patrat4SHOTCARD: //Stalfos 3
19004 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,up,-1, getUID(),false));
19005 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19006 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
19007 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,down,-1, getUID(),false));
19008 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19009 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
19010 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,left,-1, getUID(),false));
19011 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19012 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
19013 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,right,-1, getUID(),false));
19014 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19015 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
19016 break;
19017
19018 default:
19019 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
19020 if (dmisc28 == patratBREATH) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle += (zc_rand(20,-20)/100.0)*PI;
19021 double anglestore = ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle;
19022 if (dmisc28 == patrat1SHOTFAST || dmisc28 == patrat3SHOTFAST || dmisc28 == patrat5SHOTFAST) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= 2;
19023 if (dmisc28 == patrat3SHOT || dmisc28 == patrat3SHOTFAST || dmisc28 == patrat5SHOT || dmisc28 == patrat5SHOTFAST)
19024 {
19025 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
19026 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle = anglestore + (double)0.46364761;
19027 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step += 0.1180;
19028 if (dmisc28 == patrat3SHOTFAST || dmisc28 == patrat5SHOTFAST) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= 2;
19029 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
19030 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle = anglestore - (double)0.46364761;
19031 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step += 0.1180;
19032 if (dmisc28 == patrat3SHOTFAST || dmisc28 == patrat5SHOTFAST) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= 2;
19033 if (dmisc28 == patrat5SHOT || dmisc28 == patrat5SHOTFAST)
19034 {
19035 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
19036 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle = anglestore + (double)0.78539816;
19037 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step += 0.4142;
19038 if (dmisc28 == patrat5SHOTFAST) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= 2;
19039 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
19040 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle = anglestore - (double)0.78539816;
19041 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step += 0.4142;
19042 if (dmisc28 == patrat5SHOTFAST) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= 2;
19043 }
19044 }
19045 break;
19046
19047 }
19048 sfx(wpnsfx(wpn),pan(int32_t(x)));
19049 //+0.46364761
19050 //11.80
19051 }
19052
19053 void ePatra::draw(BITMAP *dest)
19054 {
19055 tile=o_tile;
19056 update_enemy_frame();
19057 enemy::draw(dest);
19058 }
19059
19060 int32_t ePatra::defend(int32_t wpnId, int32_t *power, int32_t edef)
19061 {
19062 int32_t ret = enemy::defend(wpnId, power, edef);
19063
19064 if(ret < 0 && (flycnt||flycnt2))
19065 return 0;
19066
19067 return ret;
19068 }
19069
19070 int32_t ePatra::defendNew(int32_t wpnId, int32_t *power, int32_t edef, byte unblockable)
19071 {
19072 int32_t ret = enemy::defendNew(wpnId, power, edef, unblockable);
19073
19074 if(ret < 0 && (flycnt||flycnt2))
19075 return 0;
19076
19077 return ret;
19078 }
19079
19080 esPatra::esPatra(zfix X,zfix Y,int32_t Id,int32_t Clk, sprite * prnt) : enemy(X,Y,Id,Clk), parent(prnt)
19081 {
19082 //cs=8;
19083 item_set=0;
19084 misc=clk;
19085 clk4 = 0;
19086 clk5 = 0;
19087 clk = -((misc*21)>>1)-1;
19088 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
19089 hxsz=12;
19090 hysz=12;
19091 hxofs=2;
19092 hyofs=2;
19093 extend = 0;
19094 txsz = 1;
19095 tysz = 1;
19096 /* //These need to be separate enemy editor fields. This enemy class also it's draw altered to correctly support big stuff.
19097 enemy *prntenemy = (enemy *) guys.getByUID(parent->getUID());
19098 int32_t prntSIZEflags = prntenemy->SIZEflags;
19099 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = prntenemy->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
19100 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
19101 // al_trace("Enemy txsz:%i\n", txsz);
19102 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = prntenemy->tysz; if ( tysz > 1 ) extend = 3; }
19103 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = prntenemy->hxsz;
19104 else
19105 hxsz=12;
19106 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = prntenemy->hysz;
19107 else
19108 hysz=12;
19109 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = prntenemy->hzsz;
19110 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = prntenemy->hxofs;
19111 else
19112 hxofs=2;
19113 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = prntenemy->hyofs;
19114 else hyofs=2;
19115 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
19116 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)prntenemy->xofs;
19117 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
19118 {
19119 yofs = (int32_t)prntenemy->yofs; //This seems to be setting to +48 or something with any value set?! -Z
19120 }
19121
19122 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)prntenemy->zofs;
19123 */
19124 mainguy=count_enemy=false;
19125 bgsfx=-1;
19126 //o_tile=0;
19127 flags &= (~guy_neverret);
19128 deadsfx = WAV_EDEAD;
19129 hitsfx = WAV_EHIT;
19130 isCore = false;
19131 }
19132
19133 bool esPatra::animate(int32_t index)
19134 {
19135 if(switch_hooked) return enemy::animate(index);
19136 if(dying)
19137 return Dead(index);
19138
19139 return enemy::animate(index);
19140 }
19141
19142 void esPatra::draw(BITMAP *dest)
19143 {
19144 if(get_bit(quest_rules,qr_NEWENEMYTILES))
19145 {
19146 tile = o_tile+(clk&3);
19147
19148 switch(dir) //directions get screwed up after 8. *shrug*
19149 {
19150 case up: //u
19151 flip=0;
19152 break;
19153
19154 case down: //d
19155 flip=0;
19156 tile+=4;
19157 break;
19158
19159 case left: //l
19160 flip=0;
19161 tile+=8;
19162 break;
19163
19164 case right: //r
19165 flip=0;
19166 tile+=12;
19167 break;
19168
19169 case l_up: //ul
19170 flip=0;
19171 tile+=20;
19172 break;
19173
19174 case r_up: //ur
19175 flip=0;
19176 tile+=24;
19177 break;
19178
19179 case l_down: //dl
19180 flip=0;
19181 tile+=28;
19182 break;
19183
19184 case r_down: //dr
19185 flip=0;
19186 tile+=32;
19187 break;
19188 }
19189 }
19190 else
19191 {
19192 tile = o_tile+((clk&2)>>1);
19193 }
19194
19195 if(clk>=0)
19196 enemy::draw(dest);
19197 }
19198
19199
19200 ePatraBS::ePatraBS(zfix ,zfix ,int32_t Id,int32_t Clk) : enemy((zfix)128,(zfix)48,Id,Clk)
19201 {
19202 adjusted=false;
19203 dir=(zc_oldrand()&7)+8;
19204 step=0.25;
19205 clk4 = 0;
19206 clk5 = 0;
19207 //flycnt=6; flycnt2=0;
19208 flycnt=dmisc1;
19209 flycnt2=0; // PatraBS doesn't have inner rings!
19210 loopcnt=0;
19211
19212 SIZEflags = d->SIZEflags;
19213 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
19214 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
19215 // al_trace("Enemy txsz:%i\n", txsz);
19216 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
19217 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
19218 else hxsz = 32;
19219 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
19220 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
19221 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
19222 else hxofs=-8;
19223 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
19224 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
19225 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
19226 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
19227 {
19228 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
19229 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
19230 }
19231
19232 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
19233
19234 if(dmisc6<int16_t(1))dmisc6=1; // ratio cannot be 0!
19235
19236 //nets+4480;
19237 }
19238
19239 bool ePatraBS::animate(int32_t index)
19240 {
19241 if(switch_hooked) return enemy::animate(index);
19242 if(dying)
19243 return Dead(index);
19244
19245 if(clk==0)
19246 {
19247 removearmos(x,y,ffcactivated);
19248 }
19249
19250 variable_walk_8(rate,homing,hrate,spw_floater);
19251
19252 if(++clk2>90)
19253 {
19254 clk2=0;
19255
19256 if(loopcnt)
19257 --loopcnt;
19258 else
19259 {
19260 if((misc%dmisc6)==0)
19261 loopcnt=dmisc7;
19262 }
19263
19264 ++misc;
19265 }
19266
19267 // double size=1;;
19268 for(int32_t i=index+1; i<index+flycnt+1; i++)
19269 {
19270 if(!adjusted)
19271 {
19272 ((enemy*)guys.spr(i))->hp=dmisc3;
19273
19274 if(get_bit(quest_rules,qr_NEWENEMYTILES))
19275 {
19276 ((enemy*)guys.spr(i))->o_tile=o_tile+dmisc8;
19277 }
19278 else
19279 {
19280 ((enemy*)guys.spr(i))->o_tile=o_tile+1;
19281 }
19282
19283 ((enemy*)guys.spr(i))->cs = dmisc9;
19284 }
19285
19286 if(((enemy*)guys.spr(i))->hp <= 0)
19287 {
19288 for(int32_t j=i; j<index+flycnt+flycnt2; j++)
19289 {
19290 guys.swap(j,j+1);
19291 }
19292
19293 --flycnt;
19294 }
19295 else
19296 {
19297 int32_t pos2 = ((enemy*)guys.spr(i))->misc;
19298 double a2 = ((int64_t)clk2-pos2*90/(dmisc1==0?1:dmisc1))*PI/45;
19299 temp_x = zc::math::Cos(a2+PI/2)*45;
19300 temp_y = -zc::math::Sin(a2+PI/2)*45;
19301
19302 if(loopcnt>0)
19303 {
19304 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*45;
19305 guys.spr(i)->y = (-zc::math::Sin(a2+PI/2)-zc::math::Cos(pos2*PI*2/(dmisc1==0?1:dmisc1)))*22.5;
19306 }
19307 else
19308 {
19309 guys.spr(i)->x = temp_x;
19310 guys.spr(i)->y = temp_y;
19311 }
19312
19313 double _MSVC2022_tmp1, _MSVC2022_tmp2;
19314 double ddir=atan2_MSVC2022_FIX(double(temp_y),double(temp_x));
19315
19316 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
19317 {
19318 guys.spr(i)->dir=l_down;
19319 }
19320 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
19321 {
19322 guys.spr(i)->dir=left;
19323 }
19324 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
19325 {
19326 guys.spr(i)->dir=l_up;
19327 }
19328 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
19329 {
19330 guys.spr(i)->dir=up;
19331 }
19332 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
19333 {
19334 guys.spr(i)->dir=r_up;
19335 }
19336 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
19337 {
19338 guys.spr(i)->dir=right;
19339 }
19340 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
19341 {
19342 guys.spr(i)->dir=r_down;
19343 }
19344 else
19345 {
19346 guys.spr(i)->dir=down;
19347 }
19348
19349 guys.spr(i)->x += x;
19350 guys.spr(i)->y += y;
19351 }
19352 }
19353
19354 adjusted=true;
19355 return enemy::animate(index);
19356 }
19357
19358 void ePatraBS::draw(BITMAP *dest)
19359 {
19360 tile=o_tile;
19361
19362 if(get_bit(quest_rules,qr_NEWENEMYTILES))
19363 {
19364 double _MSVC2022_tmp1, _MSVC2022_tmp2;
19365 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
19366
19367 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
19368 {
19369 lookat=l_down;
19370 }
19371 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
19372 {
19373 lookat=down;
19374 }
19375 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
19376 {
19377 lookat=r_down;
19378 }
19379 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
19380 {
19381 lookat=right;
19382 }
19383 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
19384 {
19385 lookat=r_up;
19386 }
19387 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
19388 {
19389 lookat=up;
19390 }
19391 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
19392 {
19393 lookat=l_up;
19394 }
19395 else
19396 {
19397 lookat=left;
19398 }
19399
19400 switch(lookat) //directions get screwed up after 8. *shrug*
19401 {
19402 case up: //u
19403 flip=0;
19404 break;
19405
19406 case down: //d
19407 flip=0;
19408 tile+=8;
19409 break;
19410
19411 case left: //l
19412 flip=0;
19413 tile+=40;
19414 break;
19415
19416 case right: //r
19417 flip=0;
19418 tile+=48;
19419 break;
19420
19421 case l_up: //ul
19422 flip=0;
19423 tile+=80;
19424 break;
19425
19426 case r_up: //ur
19427 flip=0;
19428 tile+=88;
19429 break;
19430
19431 case l_down: //dl
19432 flip=0;
19433 tile+=120;
19434 break;
19435
19436 case r_down: //dr
19437 flip=0;
19438 tile+=128;
19439 break;
19440 }
19441
19442 tile+=(2*(clk&3));
19443 xofs-=8;
19444 yofs-=8;
19445 drawblock(dest,15);
19446 xofs+=8;
19447 yofs+=8;
19448 }
19449 else
19450 {
19451 flip=(clk&1);
19452 xofs-=8;
19453 yofs-=8;
19454 enemy::draw(dest);
19455 xofs+=16;
19456 enemy::draw(dest);
19457 yofs+=16;
19458 enemy::draw(dest);
19459 xofs-=16;
19460 enemy::draw(dest);
19461 xofs+=8;
19462 yofs-=8;
19463 }
19464 }
19465
19466 int32_t ePatraBS::defend(int32_t wpnId, int32_t *power, int32_t edef)
19467 {
19468 int32_t ret = enemy::defend(wpnId, power, edef);
19469
19470 if(ret < 0 && (flycnt||flycnt2))
19471 return 0;
19472
19473 return ret;
19474 }
19475
19476 int32_t ePatraBS::defendNew(int32_t wpnId, int32_t *power, int32_t edef, byte unblockable)
19477 {
19478 int32_t ret = enemy::defendNew(wpnId, power, edef, unblockable);
19479
19480 if(ret < 0 && (flycnt||flycnt2))
19481 return 0;
19482
19483 return ret;
19484 }
19485
19486 esPatraBS::esPatraBS(zfix X,zfix Y,int32_t Id,int32_t Clk, sprite * prnt) : enemy(X,Y,Id,Clk), parent(prnt)
19487 {
19488 //cs=csBOSS;
19489 item_set=0;
19490 misc=clk;
19491 clk = -((misc*21)>>1)-1;
19492 clk4 = 0;
19493 clk5 = 0;
19494 enemy *prntenemy = (enemy *) guys.getByUID(parent->getUID());
19495 int32_t prntSIZEflags = prntenemy->SIZEflags;
19496 if ( ((prntSIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = prntenemy->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
19497 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
19498 // al_trace("Enemy txsz:%i\n", txsz);
19499 if ( ((prntSIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = prntenemy->tysz; if ( tysz > 1 ) extend = 3; }
19500 if ( ((prntSIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = prntenemy->hxsz;
19501 else hxsz=16;
19502 if ( ((prntSIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = prntenemy->hysz;
19503 else hysz=16;
19504 if ( ((prntSIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = prntenemy->hzsz;
19505 if ( (prntSIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = prntenemy->hxofs;
19506 if ( (prntSIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = prntenemy->hyofs;
19507 else hyofs=2;
19508 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
19509 if ( (prntSIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)prntenemy->xofs;
19510 if ( (prntSIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
19511 {
19512 yofs = (int32_t)prntenemy->yofs;
19513 }
19514 else yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
19515 if ( (prntSIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) prntenemy->zofs = (int32_t)zofs;
19516
19517 bgsfx=-1;
19518 mainguy=count_enemy=false;
19519 deadsfx = WAV_EDEAD;
19520 hitsfx = WAV_EHIT;
19521 flags &= ~guy_neverret;
19522 isCore = false;
19523 }
19524
19525 bool esPatraBS::animate(int32_t index)
19526 {
19527 if(switch_hooked) return enemy::animate(index);
19528 if(dying)
19529 return Dead(index);
19530
19531 return enemy::animate(index);
19532 }
19533
19534 void esPatraBS::draw(BITMAP *dest)
19535 {
19536 tile=o_tile;
19537
19538 if(get_bit(quest_rules,qr_NEWENEMYTILES))
19539 {
19540 switch(dir) //directions get screwed up after 8. *shrug*
19541 {
19542 case up: //u
19543 flip=0;
19544 break;
19545
19546 case down: //d
19547 flip=0;
19548 tile+=4;
19549 break;
19550
19551 case left: //l
19552 flip=0;
19553 tile+=8;
19554 break;
19555
19556 case right: //r
19557 flip=0;
19558 tile+=12;
19559 break;
19560
19561 case l_up: //ul
19562 flip=0;
19563 tile+=20;
19564 break;
19565
19566 case r_up: //ur
19567 flip=0;
19568 tile+=24;
19569 break;
19570
19571 case l_down: //dl
19572 flip=0;
19573 tile+=28;
19574 break;
19575
19576 case r_down: //dr
19577 flip=0;
19578 tile+=32;
19579 break;
19580 }
19581
19582 tile += ((clk&6)>>1);
19583 }
19584 else
19585 {
19586 tile += (clk&4)?1:0;
19587 }
19588
19589 if(clk>=0)
19590 enemy::draw(dest);
19591 }
19592
19593
19594 /**********************************/
19595 /********** Misc Code ***********/
19596 /**********************************/
19597
19598 18 void addEwpn(int32_t x,int32_t y,int32_t z,int32_t id,int32_t type,int32_t power,int32_t dir, int32_t parentid, byte script_generated, int32_t fakez)
19599 {
19600
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
18 if(id>wEnemyWeapons || (id >= wScript1 && id <= wScript10))
19601
4/8
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 18 times.
✗ Branch 7 not taken.
18 Ewpns.add(new weapon((zfix)x,(zfix)y,(zfix)z,id,type,power,dir, -1, parentid, script_generated));
19602
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (fakez > 0) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19603 18 }
19604
19605 32 int32_t hit_enemy(int32_t index, int32_t wpnId,int32_t power,int32_t wpnx,int32_t wpny,int32_t dir, int32_t enemyHitWeapon)
19606 {
19607 // Kludge
19608
4/8
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 32 times.
✗ Branch 7 not taken.
32 weapon *w = new weapon((zfix)wpnx,(zfix)wpny,(zfix)0,wpnId,0,power,dir,enemyHitWeapon,-1,false);
19609 32 int32_t ret= ((enemy*)guys.spr(index))->takehit(w);
19610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 delete w;
19611 32 return ret;
19612 }
19613
19614 5 void enemy_scored(int32_t index)
19615 {
19616 5 ((enemy*)guys.spr(index))->scored=true;
19617 5 }
19618
19619 12 void addguy(int32_t x,int32_t y,int32_t id,int32_t clk,bool mainguy)
19620 {
19621
6/12
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 12 times.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
12 guy *g = new guy((zfix)x,(zfix)(y+(isdungeon()?1:0)),id,get_bit(quest_rules,qr_NOGUYPOOF)?0:clk,mainguy);
19622 12 guys.add(g);
19623 12 }
19624
19625 4 void additem(int32_t x,int32_t y,int32_t id,int32_t pickup)
19626 {
19627
5/10
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
4 item *i = new item(zfix(x), zfix(y - get_bit(quest_rules, qr_NOITEMOFFSET)), zfix(0), id, pickup, 0);
19628 4 items.add(i);
19629 4 }
19630
19631 void additem(int32_t x,int32_t y,int32_t id,int32_t pickup,int32_t clk)
19632 {
19633 item *i = new item((zfix)x,(zfix)y-(get_bit(quest_rules, qr_NOITEMOFFSET)),(zfix)0,id,pickup,clk);
19634 items.add(i);
19635 }
19636
19637 void adddummyitem(int32_t x,int32_t y,int32_t id,int32_t pickup)
19638 {
19639 item *i = new item((zfix)x,(zfix)y-(get_bit(quest_rules, qr_NOITEMOFFSET)),(zfix)0,id,pickup,0,true);
19640 items.add(i);
19641 }
19642
19643 void kill_em_all()
19644 {
19645 for(int32_t i=0; i<guys.Count(); i++)
19646 {
19647 enemy *e = ((enemy*)guys.spr(i));
19648
19649 if(e->flags&(1<<3) && !(e->family == eeGHINI && e->dmisc1 == 1)) continue;
19650
19651 e->kickbucket();
19652 }
19653 }
19654
19655 bool can_kill_em_all()
19656 {
19657 for(int32_t i=0; i<guys.Count(); i++)
19658 {
19659 enemy *e = ((enemy*)guys.spr(i));
19660
19661 if(e->flags&(1<<3) && !(e->family == eeGHINI && e->dmisc1 == 1)) continue;
19662 if(e->superman) continue;
19663 return true;
19664 }
19665 return false;
19666 }
19667
19668 //This needs a quest rule, or enemy flag, Dying Enemy Doesn't Hurt Hero
19669 // For Hero's hit detection. Don't count them if they are stunned or are guys.
19670 int32_t GuyHit(int32_t tx,int32_t ty,int32_t tz,int32_t txsz,int32_t tysz,int32_t tzsz)
19671 {
19672 for(int32_t i=0; i<guys.Count(); i++)
19673 {
19674 if(guys.spr(i)->hit(tx,ty,tz,txsz,tysz,tzsz))
19675 {
19676 if(((enemy*)guys.spr(i))->stunclk==0 && ((enemy*)guys.spr(i))->frozenclock==0 && (!get_bit(quest_rules, qr_SAFEENEMYFADE) || ((enemy*)guys.spr(i))->fading != fade_flicker)
19677 &&(((enemy*)guys.spr(i))->d->family != eeGUY || ((enemy*)guys.spr(i))->dmisc1))
19678 {
19679 return i;
19680 }
19681 }
19682 }
19683
19684 return -1;
19685 }
19686
19687 23134 int32_t GuyHitFrom(int32_t index,int32_t tx,int32_t ty,int32_t tz,int32_t txsz,int32_t tysz,int32_t tzsz)
19688 {
19689
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 23134 times.
✓ Branch 2 taken 44495 times.
✓ Branch 3 taken 22890 times.
67385 for(int32_t i=zc_max(0, index); i<guys.Count(); i++)
19690 {
19691
2/2
✓ Branch 0 taken 244 times.
✓ Branch 1 taken 44251 times.
44495 if(guys.spr(i)->hit(tx,ty,tz,txsz,tysz,tzsz))
19692 {
19693 244 return i;
19694 }
19695 44251 }
19696
19697 22890 return -1;
19698 23134 }
19699
19700 // For Hero's hit detection. Count them if they are dying.
19701 30 int32_t GuyHit(int32_t index,int32_t tx,int32_t ty,int32_t tz,int32_t txsz,int32_t tysz,int32_t tzsz)
19702 {
19703 30 enemy *e = (enemy*)guys.spr(index);
19704
3/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 21 times.
30 if(!e || e->hp > 0)
19705 9 return -1;
19706
19707 21 bool d = e->dying;
19708 21 int32_t hc = e->hclk;
19709 21 e->dying = false;
19710 21 e->hclk = 0;
19711 21 bool hit = e->hit(tx,ty,tz,txsz,tysz,tzsz);
19712 21 e->dying = d;
19713 21 e->hclk = hc;
19714
19715
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 return hit ? index : -1;
19716 30 }
19717
19718 24612 bool hasMainGuy()
19719 {
19720
2/2
✓ Branch 0 taken 15253 times.
✓ Branch 1 taken 13433 times.
28686 for(int32_t i=0; i<guys.Count(); i++)
19721 {
19722
2/2
✓ Branch 0 taken 11179 times.
✓ Branch 1 taken 4074 times.
15253 if(((enemy*)guys.spr(i))->mainguy)
19723 {
19724 11179 return true;
19725 }
19726 4074 }
19727
19728 13433 return false;
19729 24612 }
19730
19731 void EatHero(int32_t index)
19732 {
19733 ((eStalfos*)guys.spr(index))->eathero();
19734 }
19735
19736 void GrabHero(int32_t index)
19737 {
19738 ((eWallM*)guys.spr(index))->grabhero();
19739 }
19740
19741 bool CarryHero()
19742 {
19743 for(int32_t i=0; i<guys.Count(); i++)
19744 {
19745 if(((guy*)(guys.spr(i)))->family==eeWALLM)
19746 {
19747 if(((eWallM*)guys.spr(i))->hashero)
19748 {
19749 Hero.x=guys.spr(i)->x;
19750 Hero.y=guys.spr(i)->y;
19751 return ((eWallM*)guys.spr(i))->misc > 0;
19752 }
19753 }
19754
19755 // Like Likes currently can't carry Hero.
19756 /*
19757 if(((guy*)(guys.spr(i)))->family==eeLIKE)
19758 {
19759 if(((eLikeLike*)guys.spr(i))->hashero)
19760 {
19761 Hero.x=guys.spr(i)->x;
19762 Hero.y=guys.spr(i)->y;
19763 return (true);
19764 }
19765 }*/
19766 }
19767
19768 return false;
19769 }
19770
19771 // Move item with guy
19772 void movefairy(zfix &x,zfix &y,int32_t misc)
19773 {
19774 int32_t i = guys.idFirst(eITEMFAIRY+0x1000*misc);
19775
19776 if(i!=-1)
19777 {
19778 x = guys.spr(i)->x;
19779 y = guys.spr(i)->y;
19780 }
19781 }
19782
19783 // Move guy with item (used by FFC scripts and hookshot-dragged fairies)
19784 void movefairy2(zfix x,zfix y,int32_t misc)
19785 {
19786 int32_t i = guys.idFirst(eITEMFAIRY+0x1000*misc);
19787
19788 if(i!=-1)
19789 {
19790 guys.spr(i)->x = x;
19791 guys.spr(i)->y = y;
19792 }
19793 }// Move item with guy
19794
19795 void movefairynew(zfix &x,zfix &y, item const &itemfairy)
19796 {
19797 enemy *fairy = (enemy *) guys.getByUID(itemfairy.fairyUID);
19798
19799 if(fairy)
19800 {
19801 x = fairy->x;
19802 y = fairy->y;
19803 }
19804 }
19805
19806 // Move guy with item (used by FFC scripts and hookshot-dragged fairies)
19807 void movefairynew2(zfix x,zfix y, item const &itemfairy)
19808 {
19809 enemy *fairy = (enemy *) guys.getByUID(itemfairy.fairyUID);
19810
19811 if(fairy)
19812 {
19813 fairy->x = x;
19814 fairy->y = y;
19815 }
19816 }
19817
19818 void killfairy(int32_t misc)
19819 {
19820 int32_t i = guys.idFirst(eITEMFAIRY+0x1000*misc);
19821 guys.del(i);
19822 }
19823
19824 int32_t getGuyIndex(const int32_t eid)
19825 {
19826 for(word i = 0; i < guys.Count(); i++)
19827 {
19828 if(guys.spr(i)->getUID() == eid)
19829 return i;
19830 }
19831
19832 return -1;
19833 }
19834
19835 void killfairynew(item const &itemfairy)
19836 {
19837 enemy *fairy = (enemy *) guys.getByUID(itemfairy.fairyUID);
19838 if (fairy != NULL) guys.del(getGuyIndex(itemfairy.fairyUID));
19839 }
19840
19841 //Should probably change this to return an 'enemy*', null on failure -Em
19842 15 int32_t addenemy(int32_t x,int32_t y,int32_t id,int32_t clk)
19843 {
19844 15 return addenemy(x,y,0,id,clk);
19845 }
19846
19847 int32_t addchild(int32_t x,int32_t y,int32_t id,int32_t clk, int32_t parent_scriptUID)
19848 {
19849 return addchild(x,y,0,id,clk, parent_scriptUID);
19850 }
19851
19852 int32_t addchild(int32_t x,int32_t y,int32_t z,int32_t id,int32_t clk, int32_t parent_scriptUID)
19853 {
19854 if(id <= 0) return 0;
19855
19856 int32_t ret = 0;
19857 sprite *e=NULL;
19858 al_trace("Adding child\n");
19859
19860 switch(guysbuf[id&0xFFF].family)
19861 {
19862 //Fixme: possible enemy memory leak. (minor)
19863 case eeWALK:
19864 e = new eStalfos((zfix)x,(zfix)y,id,clk);
19865 break;
19866
19867 case eeLEV:
19868 e = new eLeever((zfix)x,(zfix)y,id,clk);
19869 break;
19870
19871 case eeTEK:
19872 e = new eTektite((zfix)x,(zfix)y,id,clk);
19873 break;
19874
19875 case eePEAHAT:
19876 e = new ePeahat((zfix)x,(zfix)y,id,clk);
19877 break;
19878
19879 case eeZORA:
19880 e = new eZora((zfix)x,(zfix)y,id,clk);
19881 break;
19882
19883 case eeGHINI:
19884 e = new eGhini((zfix)x,(zfix)y,id,clk);
19885 break;
19886
19887 case eeKEESE:
19888 e = new eKeese((zfix)x,(zfix)y,id,clk);
19889 break;
19890
19891 case eeWIZZ:
19892 e = new eWizzrobe((zfix)x,(zfix)y,id,clk);
19893 break;
19894
19895 case eePROJECTILE:
19896 e = new eProjectile((zfix)x,(zfix)y,id,clk);
19897 break;
19898
19899 case eeWALLM:
19900 e = new eWallM((zfix)x,(zfix)y,id,clk);
19901 break;
19902
19903 case eeAQUA:
19904 e = new eAquamentus((zfix)x,(zfix)y,id,clk);
19905 break;
19906
19907 case eeMOLD:
19908 e = new eMoldorm((zfix)x,(zfix)y,id,zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)));
19909 break;
19910
19911 case eeMANHAN:
19912 e = new eManhandla((zfix)x,(zfix)y,id,clk);
19913 break;
19914
19915 case eeGLEEOK:
19916 e = new eGleeok((zfix)x,(zfix)y,id,zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)));
19917 break;
19918
19919 case eeGHOMA:
19920 e = new eGohma((zfix)x,(zfix)y,id,clk);
19921 break;
19922
19923 case eeLANM:
19924 e = new eLanmola((zfix)x,(zfix)y,id,zc_max(1,zc_min(253,guysbuf[id&0xFFF].misc1)));
19925 break;
19926
19927 case eeGANON:
19928 e = new eGanon((zfix)x,(zfix)y,id,clk);
19929 break;
19930
19931 case eeFAIRY:
19932 e = new eItemFairy((zfix)x,(zfix)y,id+0x1000*clk,clk);
19933 break;
19934
19935 case eeFIRE:
19936 e = new eFire((zfix)x,(zfix)y,id,clk);
19937 break;
19938
19939 case eeOTHER:
19940 e = new eOther((zfix)x,(zfix)y,id,clk);
19941 break;
19942
19943
19944 case eeSCRIPT01:
19945 case eeSCRIPT02:
19946 case eeSCRIPT03:
19947 case eeSCRIPT04:
19948 case eeSCRIPT05:
19949 case eeSCRIPT06:
19950 case eeSCRIPT07:
19951 case eeSCRIPT08:
19952 case eeSCRIPT09:
19953 case eeSCRIPT10:
19954 case eeSCRIPT11:
19955 case eeSCRIPT12:
19956 case eeSCRIPT13:
19957 case eeSCRIPT14:
19958 case eeSCRIPT15:
19959 case eeSCRIPT16:
19960 case eeSCRIPT17:
19961 case eeSCRIPT18:
19962 case eeSCRIPT19:
19963 case eeSCRIPT20:
19964 {
19965 if ( !get_bit(quest_rules, qr_SCRIPT_FRIENDLY_ENEMY_TYPES) )
19966 {
19967 e = new eScript((zfix)x,(zfix)y,id,clk);
19968 break;
19969 }
19970 else return 0;
19971 }
19972
19973 case eeFFRIENDLY01:
19974 case eeFFRIENDLY02:
19975 case eeFFRIENDLY03:
19976 case eeFFRIENDLY04:
19977 case eeFFRIENDLY05:
19978 case eeFFRIENDLY06:
19979 case eeFFRIENDLY07:
19980 case eeFFRIENDLY08:
19981 case eeFFRIENDLY09:
19982 case eeFFRIENDLY10:
19983 {
19984 if ( !get_bit(quest_rules, qr_SCRIPT_FRIENDLY_ENEMY_TYPES) )
19985 {
19986 e = new eFriendly((zfix)x,(zfix)y,id,clk); break;
19987 }
19988 else return 0;
19989
19990 }
19991
19992 case eeSPINTILE:
19993 e = new eSpinTile((zfix)x,(zfix)y,id,clk);
19994 break;
19995
19996 // and these enemies use the misc10/misc2 value
19997 case eeROCK:
19998 {
19999 switch(guysbuf[id&0xFFF].misc10)
20000 {
20001 case 1:
20002 e = new eBoulder((zfix)x,(zfix)y,id,clk);
20003 break;
20004
20005 case 0:
20006 default:
20007 e = new eRock((zfix)x,(zfix)y,id,clk);
20008 break;
20009 }
20010
20011 break;
20012 }
20013
20014 case eeTRAP:
20015 {
20016 switch(guysbuf[id&0xFFF].misc2)
20017 {
20018 case 1:
20019 e = new eTrap2((zfix)x,(zfix)y,id,clk);
20020 break;
20021
20022 case 0:
20023 default:
20024 e = new eTrap((zfix)x,(zfix)y,id,clk);
20025 break;
20026 }
20027
20028 break;
20029 }
20030
20031 case eeDONGO:
20032 {
20033 switch(guysbuf[id&0xFFF].misc10)
20034 {
20035 case 1:
20036 e = new eDodongo2((zfix)x,(zfix)y,id,clk);
20037 break;
20038
20039 case 0:
20040 default:
20041 e = new eDodongo((zfix)x,(zfix)y,id,clk);
20042 break;
20043 }
20044
20045 break;
20046 }
20047
20048 case eeDIG:
20049 {
20050 switch(guysbuf[id&0xFFF].misc10)
20051 {
20052 case 1:
20053 e = new eLilDig((zfix)x,(zfix)y,id,clk);
20054 break;
20055
20056 case 0:
20057 default:
20058 e = new eBigDig((zfix)x,(zfix)y,id,clk);
20059 break;
20060 }
20061
20062 break;
20063 }
20064
20065 case eePATRA:
20066 {
20067 switch(guysbuf[id&0xFFF].misc10)
20068 {
20069 case 1:
20070 if (get_bit(quest_rules,qr_HARDCODED_BS_PATRA))
20071 {
20072 e = new ePatraBS((zfix)x,(zfix)y,id,clk);
20073 break;
20074 }
20075 [[fallthrough]];
20076 case 0:
20077 default:
20078 e = new ePatra((zfix)x,(zfix)y,id,clk);
20079 break;
20080 }
20081
20082 break;
20083 }
20084
20085 case eeGUY:
20086 {
20087 switch(guysbuf[id&0xFFF].misc10)
20088 {
20089 case 1:
20090 e = new eTrigger((zfix)x,(zfix)y,id,clk);
20091 break;
20092
20093 case 0:
20094 default:
20095 e = new eNPC((zfix)x,(zfix)y,id,clk);
20096 break;
20097 }
20098
20099 break;
20100 }
20101
20102 case eeNONE:
20103 if(guysbuf[id&0xFFF].misc10 ==1)
20104 {
20105 e = new eTrigger((zfix)x,(zfix)y,id,clk);
20106 break;
20107 break;
20108 }
20109 [[fallthrough]];
20110 default:
20111
20112 return 0;
20113 }
20114
20115 ret++; // Made one enemy.
20116
20117 if(z && canfall(id))
20118 {
20119 e->z = (zfix)z;
20120 }
20121
20122 ((enemy*)e)->ceiling = (z && canfall(id));
20123 ((enemy*)e)->parent_script_UID = parent_scriptUID;
20124 //al_trace("Child Script UID: %d\n",((enemy*)e)->script_UID);
20125 //zprint2("Child Script UID: %d\n",((enemy*)e)->script_UID);
20126 //al_trace("Child's Parent UID: %d\n",((enemy*)e)->parent_script_UID);
20127 //zprint2("Child's Parent UID: %d\n",((enemy*)e)->parent_script_UID);
20128
20129
20130 if(!guys.add(e))
20131 {
20132 return 0;
20133 }
20134
20135 // add segments of segmented enemies
20136 int32_t c=0;
20137
20138 switch(guysbuf[id&0xFFF].family)
20139 {
20140 case eeMOLD:
20141 {
20142 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
20143 id &= 0xFFF;
20144
20145 for(int32_t i=0; i<zc_max(1,zc_min(254,guysbuf[id].misc1)); i++)
20146 {
20147 //christ this is messy -DD
20148 int32_t segclk = -i*((int32_t)(8.0/(zslongToFix(guysbuf[id&0xFFF].step*100))));
20149
20150 if(!guys.add(new esMoldorm((zfix)x,(zfix)y,id+0x1000,segclk)))
20151 {
20152 al_trace("Moldorm segment %d could not be created!\n",i+1);
20153
20154 for(int32_t j=0; j<i+1; j++)
20155 guys.del(guys.Count()-1);
20156
20157 return 0;
20158 }
20159
20160 if(i>0)
20161 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
20162
20163 ret++;
20164 }
20165
20166 break;
20167 }
20168
20169 case eeLANM:
20170 {
20171 id &= 0xFFF;
20172 int32_t shft = guysbuf[id].misc2;
20173 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
20174
20175 if(!guys.add(new esLanmola((zfix)x,(zfix)y,id+0x1000,0)))
20176 {
20177 al_trace("Lanmola segment 1 could not be created!\n");
20178 guys.del(guys.Count()-1);
20179 return 0;
20180 }
20181
20182 ret++;
20183
20184 for(int32_t i=1; i<zc_max(1,zc_min(253,guysbuf[id&0xFFF].misc1)); i++)
20185 {
20186 if(!guys.add(new esLanmola((zfix)x,(zfix)y,id+0x2000,-(i<<shft))))
20187 {
20188 al_trace("Lanmola segment %d could not be created!\n",i+1);
20189
20190 for(int32_t j=0; j<i+1; j++)
20191 guys.del(guys.Count()-1);
20192
20193 return 0;
20194 }
20195
20196 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
20197 ret++;
20198 }
20199 }
20200 break;
20201
20202 case eeMANHAN:
20203 id &= 0xFFF;
20204
20205 for(int32_t i=0; i<((!(guysbuf[id].misc2))?4:8); i++)
20206 {
20207 if(!guys.add(new esManhandla((zfix)x,(zfix)y,id+0x1000,i)))
20208 {
20209 al_trace("Manhandla head %d could not be created!\n",i+1);
20210
20211 for(int32_t j=0; j<i+1; j++)
20212 {
20213 guys.del(guys.Count()-1);
20214 }
20215
20216 return 0;
20217 }
20218
20219 ret++;
20220 ((enemy*)guys.spr(guys.Count()-1))->frate=guysbuf[id].misc1;
20221 }
20222
20223 break;
20224
20225 case eeGLEEOK:
20226 {
20227 id &= 0xFFF;
20228
20229 for(int32_t i=0; i<zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)); i++)
20230 {
20231 if(!guys.add(new esGleeok((zfix)x,(zfix)y,id+0x1000,c, e)))
20232 {
20233 al_trace("Gleeok head %d could not be created!\n",i+1);
20234
20235 for(int32_t j=0; j<i+1; j++)
20236 {
20237 guys.del(guys.Count()-1);
20238 }
20239
20240 return false;
20241 }
20242
20243 c-=guysbuf[id].misc4;
20244 ret++;
20245 }
20246 }
20247 break;
20248
20249
20250 case eePATRA:
20251 {
20252 id &= 0xFFF;
20253 int32_t outeyes = 0;
20254
20255 for(int32_t i=0; i<zc_min(254,guysbuf[id&0xFFF].misc1); i++)
20256 {
20257 if(!((guysbuf[id].misc10&&get_bit(quest_rules,qr_HARDCODED_BS_PATRA))?guys.add(new esPatraBS((zfix)x,(zfix)y,id+0x1000,i,e)):guys.add(new esPatra((zfix)x,(zfix)y,id+0x1000,i,e))))
20258 {
20259 al_trace("Patra outer eye %d could not be created!\n",i+1);
20260
20261 for(int32_t j=0; j<i+1; j++)
20262 guys.del(guys.Count()-1);
20263
20264 return 0;
20265 }
20266 else
20267 outeyes++;
20268
20269 ret++;
20270 }
20271
20272 for(int32_t i=0; i<zc_min(254,guysbuf[id&0xFFF].misc2); i++)
20273 {
20274 if(!guys.add(new esPatra((zfix)x,(zfix)y,id+0x1000,i,e)))
20275 {
20276 al_trace("Patra inner eye %d could not be created!\n",i+1);
20277
20278 for(int32_t j=0; j<i+1+zc_min(254,outeyes); j++)
20279 guys.del(guys.Count()-1);
20280
20281 return 0;
20282 }
20283
20284 ret++;
20285 }
20286
20287 break;
20288 }
20289 }
20290
20291 return ret;
20292 }
20293
20294 // Returns number of enemies/segments created
20295 136 int32_t addenemy(int32_t x,int32_t y,int32_t z,int32_t id,int32_t clk)
20296 {
20297 //zprint2("addenemy id is: %d\n", (id&0xFFF));
20298 136 int32_t realid = id&0xFFF;
20299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 136 times.
136 if( realid > MAXGUYS )
20300 {
20301 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "addenemy()");
20302 return 0;
20303 }
20304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 136 times.
136 if(id <= 0) return 0;
20305
20306 136 int32_t ret = 0;
20307 136 sprite *e=NULL;
20308
20309
8/31
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 94 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 17 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✓ Branch 12 taken 8 times.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
136 switch(guysbuf[id&0xFFF].family)
20310 {
20311 //Fixme: possible enemy memory leak. (minor)
20312 case eeWALK:
20313
3/6
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 94 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 94 times.
✗ Branch 5 not taken.
94 e = new eStalfos((zfix)x,(zfix)y,id,clk);
20314 94 break;
20315
20316 case eeLEV:
20317
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 e = new eLeever((zfix)x,(zfix)y,id,clk);
20318 4 break;
20319
20320 case eeTEK:
20321
3/6
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 e = new eTektite((zfix)x,(zfix)y,id,clk);
20322 8 break;
20323
20324 case eePEAHAT:
20325 e = new ePeahat((zfix)x,(zfix)y,id,clk);
20326 break;
20327
20328 case eeZORA:
20329
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 e = new eZora((zfix)x,(zfix)y,id,clk);
20330 2 break;
20331
20332 case eeGHINI:
20333 e = new eGhini((zfix)x,(zfix)y,id,clk);
20334 break;
20335
20336 case eeKEESE:
20337
3/6
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17 times.
✗ Branch 5 not taken.
17 e = new eKeese((zfix)x,(zfix)y,id,clk);
20338 17 break;
20339
20340 case eeWIZZ:
20341 e = new eWizzrobe((zfix)x,(zfix)y,id,clk);
20342 break;
20343
20344 case eePROJECTILE:
20345
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 e = new eProjectile((zfix)x,(zfix)y,id,clk);
20346 2 break;
20347
20348 case eeWALLM:
20349
3/6
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 e = new eWallM((zfix)x,(zfix)y,id,clk);
20350 8 break;
20351
20352 case eeAQUA:
20353
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 e = new eAquamentus((zfix)x,(zfix)y,id,clk);
20354 1 break;
20355
20356 case eeMOLD:
20357 e = new eMoldorm((zfix)x,(zfix)y,id,zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)));
20358 break;
20359
20360 case eeMANHAN:
20361 e = new eManhandla((zfix)x,(zfix)y,id,clk);
20362 break;
20363
20364 case eeGLEEOK:
20365 e = new eGleeok((zfix)x,(zfix)y,id,zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)));
20366 break;
20367
20368 case eeGHOMA:
20369 e = new eGohma((zfix)x,(zfix)y,id,clk);
20370 break;
20371
20372 case eeLANM:
20373 e = new eLanmola((zfix)x,(zfix)y,id,zc_max(1,zc_min(253,guysbuf[id&0xFFF].misc1)));
20374 break;
20375
20376 case eeGANON:
20377 e = new eGanon((zfix)x,(zfix)y,id,clk);
20378 break;
20379
20380 case eeFAIRY:
20381 e = new eItemFairy((zfix)x,(zfix)y,id+0x1000*clk,clk);
20382 break;
20383
20384 case eeFIRE:
20385 e = new eFire((zfix)x,(zfix)y,id,clk);
20386 break;
20387
20388 case eeOTHER:
20389 e = new eOther((zfix)x,(zfix)y,id,clk);
20390 break;
20391
20392
20393 case eeSCRIPT01:
20394 case eeSCRIPT02:
20395 case eeSCRIPT03:
20396 case eeSCRIPT04:
20397 case eeSCRIPT05:
20398 case eeSCRIPT06:
20399 case eeSCRIPT07:
20400 case eeSCRIPT08:
20401 case eeSCRIPT09:
20402 case eeSCRIPT10:
20403 case eeSCRIPT11:
20404 case eeSCRIPT12:
20405 case eeSCRIPT13:
20406 case eeSCRIPT14:
20407 case eeSCRIPT15:
20408 case eeSCRIPT16:
20409 case eeSCRIPT17:
20410 case eeSCRIPT18:
20411 case eeSCRIPT19:
20412 case eeSCRIPT20:
20413 {
20414 if ( !get_bit(quest_rules, qr_SCRIPT_FRIENDLY_ENEMY_TYPES) )
20415 {
20416 e = new eScript((zfix)x,(zfix)y,id,clk);
20417 break;
20418 }
20419 else return 0;
20420 }
20421
20422 case eeFFRIENDLY01:
20423 case eeFFRIENDLY02:
20424 case eeFFRIENDLY03:
20425 case eeFFRIENDLY04:
20426 case eeFFRIENDLY05:
20427 case eeFFRIENDLY06:
20428 case eeFFRIENDLY07:
20429 case eeFFRIENDLY08:
20430 case eeFFRIENDLY09:
20431 case eeFFRIENDLY10:
20432 {
20433 if ( !get_bit(quest_rules, qr_SCRIPT_FRIENDLY_ENEMY_TYPES) )
20434 {
20435 e = new eFriendly((zfix)x,(zfix)y,id,clk); break;
20436 }
20437 else return 0;
20438
20439 }
20440
20441 case eeSPINTILE:
20442 e = new eSpinTile((zfix)x,(zfix)y,id,clk);
20443 break;
20444
20445 // and these enemies use the misc10/misc2 value
20446 case eeROCK:
20447 {
20448 switch(guysbuf[id&0xFFF].misc10)
20449 {
20450 case 1:
20451 e = new eBoulder((zfix)x,(zfix)y,id,clk);
20452 break;
20453
20454 case 0:
20455 default:
20456 e = new eRock((zfix)x,(zfix)y,id,clk);
20457 break;
20458 }
20459
20460 break;
20461 }
20462
20463 case eeTRAP:
20464 {
20465 switch(guysbuf[id&0xFFF].misc2)
20466 {
20467 case 1:
20468 e = new eTrap2((zfix)x,(zfix)y,id,clk);
20469 break;
20470
20471 case 0:
20472 default:
20473 e = new eTrap((zfix)x,(zfix)y,id,clk);
20474 break;
20475 }
20476
20477 break;
20478 }
20479
20480 case eeDONGO:
20481 {
20482 switch(guysbuf[id&0xFFF].misc10)
20483 {
20484 case 1:
20485 e = new eDodongo2((zfix)x,(zfix)y,id,clk);
20486 break;
20487
20488 case 0:
20489 default:
20490 e = new eDodongo((zfix)x,(zfix)y,id,clk);
20491 break;
20492 }
20493
20494 break;
20495 }
20496
20497 case eeDIG:
20498 {
20499 switch(guysbuf[id&0xFFF].misc10)
20500 {
20501 case 1:
20502 e = new eLilDig((zfix)x,(zfix)y,id,clk);
20503 break;
20504
20505 case 0:
20506 default:
20507 e = new eBigDig((zfix)x,(zfix)y,id,clk);
20508 break;
20509 }
20510
20511 break;
20512 }
20513
20514 case eePATRA:
20515 {
20516 switch(guysbuf[id&0xFFF].misc10)
20517 {
20518 case 1:
20519 if (get_bit(quest_rules,qr_HARDCODED_BS_PATRA))
20520 {
20521 e = new ePatraBS((zfix)x,(zfix)y,id,clk);
20522 break;
20523 }
20524 [[fallthrough]];
20525 case 0:
20526 default:
20527 e = new ePatra((zfix)x,(zfix)y,id,clk);
20528 break;
20529 }
20530
20531 break;
20532 }
20533
20534 case eeGUY:
20535 {
20536 switch(guysbuf[id&0xFFF].misc10)
20537 {
20538 case 1:
20539 e = new eTrigger((zfix)x,(zfix)y,id,clk);
20540 break;
20541
20542 case 0:
20543 default:
20544 e = new eNPC((zfix)x,(zfix)y,id,clk);
20545 break;
20546 }
20547
20548 break;
20549 }
20550
20551 case eeNONE:
20552 if(guysbuf[id&0xFFF].misc10 ==1)
20553 {
20554 e = new eTrigger((zfix)x,(zfix)y,id,clk);
20555 break;
20556 break;
20557 }
20558 [[fallthrough]];
20559 default:
20560
20561 return 0;
20562 }
20563
20564 136 ret++; // Made one enemy.
20565
20566
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 136 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
136 if(z && canfall(id))
20567 {
20568 e->z = (zfix)z;
20569 }
20570
20571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 136 times.
136 ((enemy*)e)->ceiling = (z && canfall(id));
20572
20573
1/2
✓ Branch 0 taken 136 times.
✗ Branch 1 not taken.
136 if(!guys.add(e))
20574 {
20575 return 0;
20576 }
20577
20578 // add segments of segmented enemies
20579 136 int32_t c=0;
20580
20581
1/6
✓ Branch 0 taken 136 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
136 switch(guysbuf[id&0xFFF].family)
20582 {
20583 case eeMOLD:
20584 {
20585 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
20586 id &= 0xFFF;
20587
20588 for(int32_t i=0; i<zc_max(1,zc_min(254,guysbuf[id].misc1)); i++)
20589 {
20590 //christ this is messy -DD
20591 int32_t segclk = -i*((int32_t)(8.0/(zslongToFix(guysbuf[id&0xFFF].step*100))));
20592
20593 if(!guys.add(new esMoldorm((zfix)x,(zfix)y,id+0x1000,segclk)))
20594 {
20595 al_trace("Moldorm segment %d could not be created!\n",i+1);
20596
20597 for(int32_t j=0; j<i+1; j++)
20598 guys.del(guys.Count()-1);
20599
20600 return 0;
20601 }
20602
20603 if(i>0)
20604 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
20605
20606 ret++;
20607 }
20608
20609 break;
20610 }
20611
20612 case eeLANM:
20613 {
20614 id &= 0xFFF;
20615 int32_t shft = guysbuf[id].misc2;
20616 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
20617
20618 if(!guys.add(new esLanmola((zfix)x,(zfix)y,id+0x1000,0)))
20619 {
20620 al_trace("Lanmola segment 1 could not be created!\n");
20621 guys.del(guys.Count()-1);
20622 return 0;
20623 }
20624
20625 ret++;
20626
20627 for(int32_t i=1; i<zc_max(1,zc_min(253,guysbuf[id&0xFFF].misc1)); i++)
20628 {
20629 if(!guys.add(new esLanmola((zfix)x,(zfix)y,id+0x2000,-(i<<shft))))
20630 {
20631 al_trace("Lanmola segment %d could not be created!\n",i+1);
20632
20633 for(int32_t j=0; j<i+1; j++)
20634 guys.del(guys.Count()-1);
20635
20636 return 0;
20637 }
20638
20639 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
20640 ret++;
20641 }
20642 }
20643 break;
20644
20645 case eeMANHAN:
20646 id &= 0xFFF;
20647
20648 for(int32_t i=0; i<((!(guysbuf[id].misc2))?4:8); i++)
20649 {
20650 if(!guys.add(new esManhandla((zfix)x,(zfix)y,id+0x1000,i)))
20651 {
20652 al_trace("Manhandla head %d could not be created!\n",i+1);
20653
20654 for(int32_t j=0; j<i+1; j++)
20655 {
20656 guys.del(guys.Count()-1);
20657 }
20658
20659 return 0;
20660 }
20661
20662 ret++;
20663 ((enemy*)guys.spr(guys.Count()-1))->frate=guysbuf[id].misc1;
20664 }
20665
20666 break;
20667
20668 case eeGLEEOK:
20669 {
20670 id &= 0xFFF;
20671
20672 for(int32_t i=0; i<zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)); i++)
20673 {
20674 if(!guys.add(new esGleeok((zfix)x,(zfix)y,id+0x1000,c, e)))
20675 {
20676 al_trace("Gleeok head %d could not be created!\n",i+1);
20677
20678 for(int32_t j=0; j<i+1; j++)
20679 {
20680 guys.del(guys.Count()-1);
20681 }
20682
20683 return false;
20684 }
20685
20686 c-=guysbuf[id].misc4;
20687 ret++;
20688 }
20689 }
20690 break;
20691
20692
20693 case eePATRA:
20694 {
20695 id &= 0xFFF;
20696 int32_t outeyes = 0;
20697
20698 for(int32_t i=0; i<zc_min(254,guysbuf[id&0xFFF].misc1); i++)
20699 {
20700 if(!((guysbuf[id].misc10&&get_bit(quest_rules,qr_HARDCODED_BS_PATRA))?guys.add(new esPatraBS((zfix)x,(zfix)y,id+0x1000,i,e)):guys.add(new esPatra((zfix)x,(zfix)y,id+0x1000,i,e))))
20701 {
20702 al_trace("Patra outer eye %d could not be created!\n",i+1);
20703
20704 for(int32_t j=0; j<i+1; j++)
20705 guys.del(guys.Count()-1);
20706
20707 return 0;
20708 }
20709 else
20710 outeyes++;
20711
20712 ret++;
20713 }
20714
20715 for(int32_t i=0; i<zc_min(254,guysbuf[id&0xFFF].misc2); i++)
20716 {
20717 if(!guys.add(new esPatra((zfix)x,(zfix)y,id+0x1000,i,e)))
20718 {
20719 al_trace("Patra inner eye %d could not be created!\n",i+1);
20720
20721 for(int32_t j=0; j<i+1+zc_min(254,outeyes); j++)
20722 guys.del(guys.Count()-1);
20723
20724 return 0;
20725 }
20726
20727 ret++;
20728 }
20729
20730 break;
20731 }
20732 }
20733
20734 136 return ret;
20735 136 }
20736
20737 7000 bool isjumper(int32_t id)
20738 {
20739
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7000 times.
7000 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20740 {
20741 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "isjumper()");
20742 return false;
20743 }
20744
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7000 times.
7000 switch(guysbuf[id&0xFFF].family)
20745 {
20746 case eeROCK:
20747 case eeTEK:
20748 return true;
20749
20750 case eeWALK:
20751
2/4
✓ Branch 0 taken 7000 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7000 times.
7000 if(guysbuf[id&0xFFF].misc9==e9tVIRE || guysbuf[id&0xFFF].misc9==e9tPOLSVOICE) return true;
20752 7000 }
20753
20754 7000 return false;
20755 7000 }
20756
20757
20758 bool isfixedtogrid(int32_t id)
20759 {
20760 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20761 {
20762 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "isfixedtogrid()");
20763 return false;
20764 }
20765 switch(guysbuf[id&0xFFF].family)
20766 {
20767 case eeWALK:
20768 case eeLEV:
20769 case eeZORA:
20770 case eeDONGO:
20771 case eeGANON:
20772 case eeROCK:
20773 case eeGLEEOK:
20774 case eeAQUA:
20775 case eeLANM:
20776 return true;
20777 }
20778
20779 return false;
20780 }
20781
20782 // Can't fall, can have Z value.
20783 93504 bool isflier(int32_t id)
20784 {
20785
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 93504 times.
93504 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20786 {
20787 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "isflier()");
20788 return false;
20789 }
20790
2/2
✓ Branch 0 taken 91545 times.
✓ Branch 1 taken 1959 times.
93504 switch(guysbuf[id&0xFFF].family) //id&0x0FFF)
20791 {
20792 case eePEAHAT:
20793 case eeKEESE:
20794 case eePATRA:
20795 case eeFAIRY:
20796 case eeGHINI:
20797
20798 // Could theoretically have their Z set by a script
20799 case eeFIRE:
20800 1959 return true;
20801 break;
20802 }
20803
20804 91545 return false;
20805 93504 }
20806
20807 // Can't have Z position
20808 7000 bool never_in_air(int32_t id)
20809 {
20810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7000 times.
7000 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20811 {
20812 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "never_in_air()");
20813 return false;
20814 }
20815
1/2
✓ Branch 0 taken 7000 times.
✗ Branch 1 not taken.
7000 switch(guysbuf[id&0xFFF].family)
20816 {
20817 case eeMANHAN:
20818 case eeMOLD:
20819 case eeLANM:
20820 case eeGLEEOK:
20821 case eeZORA:
20822 case eeLEV:
20823 case eeAQUA:
20824 case eeROCK:
20825 case eeGANON:
20826 case eeTRAP:
20827 case eePROJECTILE:
20828 case eeSPINTILE:
20829 return true;
20830 }
20831
20832 7000 return false;
20833 7000 }
20834
20835 7000 bool canfall(int32_t id)
20836 {
20837
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7000 times.
7000 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20838 {
20839 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "canfall()");
20840 return false;
20841 }
20842
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 7000 times.
✗ Branch 2 not taken.
7000 switch(guysbuf[id&0xFFF].family)
20843 {
20844 case eeGUY:
20845 {
20846 if(id < eOCTO1S)
20847 return false;
20848
20849 switch(guysbuf[id&0xFFF].misc10)
20850 {
20851 case 1:
20852 case 2:
20853 return true;
20854
20855 case 0:
20856 case 3:
20857 default:
20858 return false;
20859 }
20860
20861 case eeGHOMA:
20862 case eeDIG:
20863 return false;
20864 }
20865 }
20866
20867
20868
2/4
✓ Branch 0 taken 7000 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7000 times.
7000 return !never_in_air(id) && !isflier(id) && !isjumper(id);
20869 7000 }
20870
20871 87785 bool enemy::enemycanfall(int32_t id, bool checkgrav)
20872 {
20873
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 87785 times.
87785 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20874 {
20875 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "enemycanfall()");
20876 return false;
20877 }
20878 //Z_scripterrlog("canfall family is %d:\n", family);
20879 //Z_scripterrlog("canfall gravity is %s:\n", moveflags & FLAG_OBEYS_GRAV ? "true" : "false");
20880 //if ( family == eeFIRE && id >= eSTART )
20881 //{
20882 // Z_scripterrlog("eeFire\n");
20883 // return moveflags & FLAG_OBEYS_GRAV; //'Other' enemy class, used by scripts. -Z
20884 //}
20885
20886 //In ZQ, eeFIRE is Other(floating) and eeOTHER is 'other'.
20887
20888
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 82852 times.
✓ Branch 2 taken 4933 times.
87785 switch(guysbuf[id&0xFFF].family)
20889 {
20890 case eeGUY:
20891 {
20892
1/2
✓ Branch 0 taken 4933 times.
✗ Branch 1 not taken.
4933 if(id < eOCTO1S) //screen guys and fires that aren't real enemies, and never fall
20893 4933 return false;
20894
20895 switch(guysbuf[id&0xFFF].misc10) //I'm unsure what these specify off-hand. Needs better comments. -Z
20896 {
20897 case 1:
20898 case 2:
20899 return true;
20900
20901 case 0:
20902 case 3:
20903 default:
20904 return false;
20905 }
20906
20907 case eeGHOMA:
20908 case eeDIG:
20909 return false;
20910 }
20911 }
20912
20913
2/2
✓ Branch 0 taken 49074 times.
✓ Branch 1 taken 33778 times.
82852 if(!checkgrav) return true;
20914 49074 return (moveflags & FLAG_OBEYS_GRAV);
20915
20916 // if ( isflier(id) || isjumper(id) || never_in_air(id) )
20917 // {
20918 // if ( moveflags & FLAG_OBEYS_GRAV ) return true;
20919 // else return false;
20920 // }
20921 // else
20922 // {
20923 // return (moveflags & FLAG_OBEYS_GRAV);
20924 // }
20925 //return !never_in_air(id) && !isflier(id) && !isjumper(id);
20926 87785 }
20927
20928 4 void addfires()
20929 {
20930
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(!get_bit(quest_rules,qr_NOGUYFIRES))
20931 {
20932 4 int32_t bs = get_bit(quest_rules,qr_BSZELDA);
20933 4 addguy(bs? 64: 72,64,gFIRE,-17,false);
20934 4 addguy(bs?176:168,64,gFIRE,-18,false);
20935 4 }
20936 4 }
20937
20938 61 void loadguys()
20939 {
20940
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 if(loaded_guys)
20941 return;
20942
20943 61 loaded_guys=true;
20944
20945 61 byte Guy=0;
20946 // When in caves/item rooms, use mSPECIALITEM and ipONETIME2
20947 // Else use mITEM and ipONETIME
20948 61 int32_t mf = (currscr>=128) ? mSPECIALITEM : mITEM;
20949 61 int32_t onetime = (currscr>=128) ? ipONETIME2 : ipONETIME;
20950
20951 61 repaircharge=0;
20952 61 adjustmagic=false;
20953 61 learnslash=false;
20954
20955
2/2
✓ Branch 0 taken 183 times.
✓ Branch 1 taken 61 times.
244 for(int32_t i=0; i<3; i++)
20956 {
20957 183 prices[i]=0;
20958 183 }
20959
20960 61 hasitem=0;
20961
20962
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
61 if(currscr>=128 && DMaps[currdmap].flags&dmfGUYCAVES)
20963 {
20964
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(DMaps[currdmap].flags&dmfCAVES)
20965 {
20966 3 Guy=tmpscr[1].guy;
20967 3 }
20968 3 }
20969 else
20970 {
20971 58 Guy=tmpscr->guy;
20972
20973
3/4
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
✓ Branch 3 taken 17 times.
58 if(currscr < 0x80 && (DMaps[currdmap].flags&dmfVIEWMAP))
20974 17 game->maps[(currmap*MAPSCRSNORMAL)+currscr] |= mVISITED; // mark as visited
20975 }
20976
20977 // The Guy appears if 'Hero is in cave' equals 'Guy is in cave'.
20978
4/4
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 4 times.
61 if(Guy && ((currscr>=128) == !!(DMaps[currdmap].flags&dmfGUYCAVES)))
20979 {
20980
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(tmpscr->room==rZELDA)
20981 {
20982 addguy(120,72,Guy,-15,true);
20983 guys.spr(0)->hxofs=1000;
20984 addenemy(128,96,eFIRE,-15);
20985 addenemy(112,96,eFIRE,-15);
20986 addenemy(96,120,eFIRE,-15);
20987 addenemy(144,120,eFIRE,-15);
20988 return;
20989 }
20990
20991
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if(Guy!=gFAIRY || !get_bit(quest_rules,qr_NOFAIRYGUYFIRES))
20992 4 addfires();
20993
20994
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if(currscr>=128)
20995
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if(getmapflag() && !(tmpscr->flags9&fBELOWRETURN))
20996 Guy=0;
20997
20998
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 switch(tmpscr->room)
20999 {
21000 case rSP_ITEM:
21001 case rGRUMBLE:
21002 case rBOMBS:
21003 case rARROWS:
21004 case rSWINDLE:
21005 case rMUPGRADE:
21006 case rLEARNSLASH:
21007 case rTAKEONE:
21008 if((get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag((currscr < 128) ? mITEM : mSPECIALITEM)) || (!get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag() && !(tmpscr->flags9&fBELOWRETURN))) //get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)
21009 Guy=0;
21010
21011 break;
21012
21013 case rREPAIR:
21014 if (get_bit(quest_rules, qr_OLD_DOORREPAIR)) break;
21015 if((get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag((currscr < 128) ? mITEM : mSPECIALITEM)) || (!get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag() && !(tmpscr->flags9&fBELOWRETURN))) //get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)
21016 Guy=0;
21017
21018 break;
21019 case rRP_HC:
21020 if (get_bit(quest_rules, qr_OLD_POTION_OR_HC)) break;
21021 if((get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag((currscr < 128) ? mITEM : mSPECIALITEM)) || (!get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag() && !(tmpscr->flags9&fBELOWRETURN))) //get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)
21022 Guy=0;
21023
21024 break;
21025 case rMONEY:
21026 if (get_bit(quest_rules, qr_OLD_SECRETMONEY)) break;
21027 if((get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag((currscr < 128) ? mITEM : mSPECIALITEM)) || (!get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag() && !(tmpscr->flags9&fBELOWRETURN))) //get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)
21028 Guy=0;
21029
21030 break;
21031
21032 case rTRIFORCE:
21033 {
21034 int32_t tc = TriforceCount();
21035
21036 if(get_bit(quest_rules,qr_4TRI))
21037 {
21038 if((get_bit(quest_rules,qr_3TRI) && tc>=3) || tc>=4)
21039 Guy=0;
21040 }
21041 else
21042 {
21043 if((get_bit(quest_rules,qr_3TRI) && tc>=6) || tc>=8)
21044 Guy=0;
21045 }
21046 }
21047 break;
21048 }
21049
21050
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(Guy)
21051 {
21052
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if(Guy!=gFAIRY || !get_bit(quest_rules,qr_NOFAIRYGUYFIRES))
21053 4 blockpath=true;
21054
21055
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if(currscr<128)
21056 1 sfx(WAV_SCALE);
21057
21058
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
4 addguy(120,64,Guy, (dlevel||BSZ)?-15:startguy[zc_oldrand()&7], true);
21059 4 Hero.Freeze();
21060 4 }
21061 4 }
21062
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 else if(Guy==gFAIRY) // The only Guy that somewhat ignores the "Guys In Caves Only" DMap flag
21063 {
21064 sfx(WAV_SCALE);
21065 addguy(120,62,gFAIRY,-14,false);
21066 }
21067
21068 61 loaditem();
21069
21070 // Collecting a rupee in a '10 Rupees' screen sets the mITEM screen state if
21071 // it doesn't appear in a Cave/Item Cellar, and the mSPECIALITEM screen state if it does.
21072
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
61 if(tmpscr->room==r10RUPIES && !getmapflag(mf))
21073 {
21074 //setmapflag();
21075 for(int32_t i=0; i<10; i++)
21076 additem(ten_rupies_x[i],ten_rupies_y[i],0,ipBIGRANGE+onetime,-14);
21077 }
21078 61 }
21079
21080 61 void loaditem()
21081 {
21082 61 byte Item = 0;
21083
21084
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 3 times.
61 if(currscr<128)
21085 {
21086 58 Item=tmpscr->item;
21087
21088
4/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 10 times.
58 if((!getmapflag(mITEM) || (tmpscr->flags9&fITEMRETURN)) && (tmpscr->hasitem != 0))
21089 {
21090
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(tmpscr->flags8&fSECRETITEM)
21091 hasitem=8;
21092
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6 times.
10 else if(tmpscr->flags&fITEM)
21093 4 hasitem=1;
21094
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 else if(tmpscr->enemyflags&efCARRYITEM)
21095 1 hasitem=4; // Will be set to 2 by roaming_item
21096 else
21097
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 items.add(new item((zfix)tmpscr->itemx,
21098
4/14
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 5 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 5 times.
✗ Branch 13 not taken.
5 (tmpscr->flags7&fITEMFALLS && isSideViewGravity()) ? (zfix)-170 : (zfix)tmpscr->itemy+(get_bit(quest_rules, qr_NOITEMOFFSET)?0:1),
21099
2/10
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5 times.
✗ Branch 9 not taken.
5 (tmpscr->flags7&fITEMFALLS && !(isSideViewGravity())) ? (zfix)170 : (zfix)0,
21100
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 Item,ipONETIME|ipBIGRANGE|((itemsbuf[Item].family==itype_triforcepiece ||
21101 5 (tmpscr->flags3&fHOLDITEM)) ? ipHOLDUP : 0) | ((tmpscr->flags8&fITEMSECRET) ? ipSECRETS : 0),0));
21102 10 }
21103 58 }
21104
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 else if(!(DMaps[currdmap].flags&dmfCAVES))
21105 {
21106 if((!getmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM) || (tmpscr[1].flags9&fBELOWRETURN)) && tmpscr[1].room==rSP_ITEM
21107 && (currscr==128 || !get_bit(quest_rules,qr_ITEMSINPASSAGEWAYS)))
21108 {
21109 Item=tmpscr[1].catchall;
21110
21111 if(Item)
21112 items.add(new item((zfix)tmpscr->itemx,
21113 (tmpscr->flags7&fITEMFALLS && isSideViewGravity()) ? (zfix)-170 : (zfix)tmpscr->itemy+(get_bit(quest_rules, qr_NOITEMOFFSET)?0:1),
21114 (tmpscr->flags7&fITEMFALLS && !(isSideViewGravity())) ? (zfix)170 : (zfix)0,
21115 Item,ipONETIME2|ipBIGRANGE|ipHOLDUP | ((tmpscr->flags8&fITEMSECRET) ? ipSECRETS : 0),0));
21116 }
21117 }
21118 61 }
21119
21120 1 void never_return(int32_t index)
21121 {
21122
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(!get_bit(quest_rules,qr_KILLALL))
21123 1 goto doit;
21124
21125 for(int32_t i=0; i<guys.Count(); i++)
21126 if(((((enemy*)guys.spr(i))->d->flags)&guy_neverret) && i!=index)
21127 {
21128 goto dontdoit;
21129 }
21130
21131 doit:
21132 1 setmapflag(mNEVERRET);
21133 dontdoit:
21134 1 return;
21135 }
21136
21137 120 bool slowguy(int32_t id)
21138 {
21139
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 120 times.
120 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
21140 {
21141 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "slowguy()");
21142 return false;
21143 }
21144 //return (guysbuf[id].step<100);
21145
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 62 times.
120 switch(id)
21146 {
21147 case eOCTO1S:
21148 case eOCTO2S:
21149 case eOCTO1F:
21150 case eOCTO2F:
21151 case eLEV1:
21152 case eLEV2:
21153 case eROCK:
21154 case eBOULDER:
21155 62 return true;
21156 }
21157
21158 58 return false;
21159 120 }
21160
21161 132 bool ok2add(int32_t id)
21162 {
21163
2/4
✓ Branch 0 taken 132 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 132 times.
132 if( ((unsigned)(id&0xFFF)) > MAXGUYS || id <= 0)
21164 {
21165 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "oktoadd()");
21166 return false;
21167 }
21168
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 132 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
132 if(getmapflag(mNEVERRET) && (guysbuf[id].flags & guy_neverret))
21169 return false;
21170
21171
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 132 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
132 switch(guysbuf[id].family)
21172 {
21173 // I added a special case for shooters because having traps on the same screen
21174 // was preventing them from spawning due to TMPNORET. This means they will
21175 // never stay dead, though, so it may not be the best solution. - Saf
21176 case eePROJECTILE:
21177 return true;
21178
21179
21180 case eeDIG:
21181 {
21182 switch(guysbuf[id].misc10)
21183 {
21184 case 1:
21185 if(!get_bit(quest_rules,qr_NOTMPNORET))
21186 return !getmapflag(mTMPNORET);
21187
21188 return true;
21189
21190 case 0:
21191 default:
21192 return true;
21193 }
21194 }
21195 case eeGANON:
21196 case eeTRAP:
21197 if ((guysbuf[id].family == eeGANON && !get_bit(quest_rules, qr_CAN_PLACE_GANON))
21198 || (guysbuf[id].family == eeTRAP && !get_bit(quest_rules, qr_CAN_PLACE_TRAPS))) return false;
21199 [[fallthrough]];
21200 default:
21201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 132 times.
132 if (guysbuf[id].flags2&guy_ignoretmpnr) return true;
21202 132 break;
21203 }
21204
21205
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 93 times.
132 if(!get_bit(quest_rules,qr_NOTMPNORET))
21206 93 return !getmapflag(mTMPNORET);
21207
21208 39 return true;
21209 132 }
21210
21211 void activate_fireball_statue(int32_t pos)
21212 {
21213 if(!(tmpscr->enemyflags&efFIREBALLS) || statueID<0)
21214 {
21215 return;
21216 }
21217
21218 int32_t cx=-1000, cy=-1000;
21219 int32_t x = (pos&15)<<4;
21220 int32_t y = pos&0xF0;
21221
21222 int32_t ctype = combobuf[MAPCOMBO(x,y)].type;
21223
21224 if(!isfixedtogrid(statueID))
21225 {
21226 if(ctype==cL_STATUE)
21227 {
21228 cx=x+4;
21229 cy=y+7;
21230 }
21231 else if(ctype==cR_STATUE)
21232 {
21233 cx=x-8;
21234 cy=y-1;
21235 }
21236 else if(ctype==cC_STATUE)
21237 {
21238 cx=x;
21239 cy=y;
21240 }
21241 }
21242 else if(ctype==cL_STATUE || ctype==cR_STATUE || ctype==cC_STATUE)
21243 {
21244 cx=x;
21245 cy=y;
21246 }
21247
21248 if(cx!=-1000) // No point creating it if this is false
21249 {
21250 for(int32_t j=0; j<guys.Count(); j++)
21251 {
21252 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy))
21253 {
21254 if((guys.spr(j)->id&0xFFF) == statueID) // There's already a matching enemy here!
21255 return; // No point deleting it. A script might be toying with it in some way.
21256 else
21257 guys.del(j);
21258 }
21259 }
21260
21261 addenemy(cx, cy, statueID, !isfixedtogrid(statueID) ? 24 : 0);
21262 }
21263 }
21264
21265 60 void activate_fireball_statues()
21266 {
21267
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 if(!(tmpscr->enemyflags&efFIREBALLS))
21268 {
21269 60 return;
21270 }
21271
21272 for(int32_t i=0; i<176; i++)
21273 {
21274 activate_fireball_statue(i);
21275 }
21276 60 }
21277
21278 60 void load_default_enemies()
21279 {
21280 60 wallm_load_clk=frame-80;
21281 60 int32_t Id=0;
21282
21283
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 2 times.
60 if(tmpscr->enemyflags&efZORA)
21284 {
21285
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(zoraID>=0)
21286 2 addenemy(-16, -16, zoraID, 0);
21287 2 }
21288
21289
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 if(tmpscr->enemyflags&efTRAP4)
21290 {
21291 if(cornerTrapID>=0)
21292 {
21293 addenemy(32, 32, cornerTrapID, -14);
21294 addenemy(208, 32, cornerTrapID, -14);
21295 addenemy(32, 128, cornerTrapID, -14);
21296 addenemy(208, 128, cornerTrapID, -14);
21297 }
21298 }
21299
21300
2/2
✓ Branch 0 taken 660 times.
✓ Branch 1 taken 60 times.
720 for(int32_t y=0; y<176; y+=16)
21301 {
21302
2/2
✓ Branch 0 taken 10560 times.
✓ Branch 1 taken 660 times.
11220 for(int32_t x=0; x<256; x+=16)
21303 {
21304 10560 int32_t ctype = combobuf[MAPCOMBO(x,y)].type;
21305 10560 int32_t cflag = MAPFLAG(x, y);
21306 10560 int32_t cflag_i = MAPCOMBOFLAG(x, y);
21307
21308
3/6
✓ Branch 0 taken 10560 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10560 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10560 times.
10560 if(ctype==cTRAP_H || cflag==mfTRAP_H || cflag_i==mfTRAP_H)
21309 {
21310 if(trapLOSHorizontalID>=0)
21311 addenemy(x, y, trapLOSHorizontalID, -14);
21312 }
21313
3/6
✓ Branch 0 taken 10560 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10560 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10560 times.
10560 else if(ctype==cTRAP_V || cflag==mfTRAP_V || cflag_i==mfTRAP_V)
21314 {
21315 if(trapLOSVerticalID>=0)
21316 addenemy(x, y, trapLOSVerticalID, -14);
21317 }
21318
3/6
✓ Branch 0 taken 10560 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10560 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10560 times.
10560 else if(ctype==cTRAP_4 || cflag==mfTRAP_4 || cflag_i==mfTRAP_4)
21319 {
21320 if(trapLOS4WayID>=0)
21321 {
21322 if(addenemy(x, y, trapLOS4WayID, -14))
21323 guys.spr(guys.Count()-1)->dummy_int[1]=2;
21324 }
21325 }
21326
21327
3/6
✓ Branch 0 taken 10560 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10560 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10560 times.
10560 else if(ctype==cTRAP_LR || cflag==mfTRAP_LR || cflag_i==mfTRAP_LR)
21328 {
21329 if(trapConstantHorizontalID>=0)
21330 addenemy(x, y, trapConstantHorizontalID, -14);
21331 }
21332
3/6
✓ Branch 0 taken 10560 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10560 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10560 times.
10560 else if(ctype==cTRAP_UD || cflag==mfTRAP_UD || cflag_i==mfTRAP_UD)
21333 {
21334 if(trapConstantVerticalID>=0)
21335 addenemy(x, y, trapConstantVerticalID, -14);
21336 }
21337
21338
1/2
✓ Branch 0 taken 10560 times.
✗ Branch 1 not taken.
10560 if(ctype==cSPINTILE1)
21339 {
21340 // Awaken spinning tile
21341 awaken_spinning_tile(tmpscr,COMBOPOS(x,y));
21342 }
21343 10560 }
21344 660 }
21345
21346
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 if(tmpscr->enemyflags&efTRAP2)
21347 {
21348 if(centerTrapID>=-1)
21349 {
21350 if(addenemy(64, 80, centerTrapID, -14))
21351 guys.spr(guys.Count()-1)->dummy_int[1]=1;
21352
21353 if(addenemy(176, 80, centerTrapID, -14))
21354 guys.spr(guys.Count()-1)->dummy_int[1]=1;
21355 }
21356 }
21357
21358
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 if(tmpscr->enemyflags&efROCKS)
21359 {
21360 if(rockID>=0)
21361 {
21362 addenemy(zc_oldrand()&0xF0, 0, rockID, 0);
21363 addenemy(zc_oldrand()&0xF0, 0, rockID, 0);
21364 addenemy(zc_oldrand()&0xF0, 0, rockID, 0);
21365 }
21366 }
21367
21368 60 activate_fireball_statues();
21369 60 }
21370
21371 75152 void update_slope_combopos(int32_t lyr, int32_t pos)
21372 {
21373
2/4
✓ Branch 0 taken 75152 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 75152 times.
75152 if(unsigned(lyr) > 6 || unsigned(pos) > 175) return;
21374 75152 mapscr* s = FFCore.tempScreens[lyr];
21375 75152 newcombo const& cmb = combobuf[s->data[pos]];
21376
21377 75152 auto id = (176*lyr)+pos;
21378 75152 auto it = slopes.find(id);
21379
21380 75152 bool wasSlope = it!=slopes.end();
21381 75152 bool isSlope = cmb.type == cSLOPE;
21382
21383
3/4
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 75062 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 90 times.
75152 if(isSlope && !wasSlope)
21384 {
21385 90 slopes.try_emplace(id, &(s->data[pos]), nullptr, id, pos);
21386 90 }
21387
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 75062 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
75062 else if(wasSlope && !isSlope)
21388 {
21389 slopes.erase(it);
21390 }
21391 75152 }
21392 61 void update_slope_comboposes()
21393 {
21394
2/2
✓ Branch 0 taken 427 times.
✓ Branch 1 taken 61 times.
488 for(auto lyr = 0; lyr < 7; ++lyr)
21395 {
21396
2/2
✓ Branch 0 taken 75152 times.
✓ Branch 1 taken 427 times.
75579 for(auto pos = 0; pos < 176; ++pos)
21397 75152 update_slope_combopos(lyr,pos);
21398 427 }
21399 61 }
21400
21401 // Everything that must be done before we change a screen's combo to another combo, or a combo's type to another type.
21402 // There's 2 routines because it's unclear if combobuf or tmpscr->data gets modified. -L
21403 void screen_combo_modify_preroutine(mapscr *s, int32_t pos)
21404 {
21405 delete_fireball_shooter(s, pos);
21406 }
21407
21408 //Placeholder in case we need it.
21409 void screen_ffc_modify_preroutine(word index)
21410 {
21411 return;
21412 }
21413
21414 // Everything that must be done after we change a screen's combo to another combo. -L
21415 void screen_combo_modify_postroutine(mapscr *s, int32_t pos)
21416 {
21417 s->valid |= mVALID;
21418 activate_fireball_statue(pos);
21419
21420 if(combobuf[s->data[pos]].type==cSPINTILE1)
21421 {
21422 // Awaken spinning tile
21423 awaken_spinning_tile(s,pos);
21424 }
21425 int32_t lyr = -1;
21426 if(s == tmpscr) lyr = 0;
21427 else for(size_t q = 0; q < 6; ++q)
21428 {
21429 if(s == tmpscr2+q)
21430 {
21431 lyr = q+1;
21432 break;
21433 }
21434 }
21435 if(lyr > -1)
21436 update_slope_combopos(lyr,pos);
21437 }
21438
21439 9220 void screen_ffc_modify_postroutine(word index)
21440 {
21441 9220 ffcdata& ff = tmpscr->ffcs[index];
21442 9220 newcombo const& cmb = combobuf[ff.getData()];
21443
21444 9220 auto id = (176*7)+int32_t(index);
21445 9220 auto it = slopes.find(id);
21446
21447 9220 bool wasSlope = it!=slopes.end();
21448
2/2
✓ Branch 0 taken 9118 times.
✓ Branch 1 taken 102 times.
9220 bool isSlope = cmb.type == cSLOPE && !(ff.flags&ffCHANGER);
21449
3/4
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 9126 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 94 times.
9220 if(isSlope && !wasSlope)
21450 {
21451 94 slopes.try_emplace(id, nullptr, &ff, id);
21452 94 }
21453
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9125 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
9126 else if(wasSlope && !isSlope)
21454 {
21455 1 slopes.erase(it);
21456 1 }
21457 9220 }
21458
21459 void screen_combo_modify_pre(int32_t cid)
21460 {
21461 for(auto lyr = 0; lyr < 7; ++lyr)
21462 {
21463 mapscr* t = FFCore.tempScreens[lyr];
21464 for(int32_t i = 0; i < 176; i++)
21465 {
21466 if(t->data[i] == cid)
21467 {
21468 screen_combo_modify_preroutine(t,i);
21469 }
21470 }
21471 }
21472 }
21473 void screen_combo_modify_post(int32_t cid)
21474 {
21475 for(auto lyr = 0; lyr < 7; ++lyr)
21476 {
21477 mapscr* t = FFCore.tempScreens[lyr];
21478 for(int32_t i = 0; i < 176; i++)
21479 {
21480 if(t->data[i] == cid)
21481 {
21482 screen_combo_modify_postroutine(t,i);
21483 }
21484 }
21485 }
21486 for(word ind = 0; ind < MAXFFCS; ++ind)
21487 {
21488 if(tmpscr->ffcs[ind].getData() == cid)
21489 screen_ffc_modify_postroutine(ind);
21490 }
21491 }
21492
21493 void awaken_spinning_tile(mapscr *s, int32_t pos)
21494 {
21495 addenemy((pos&15)<<4,pos&0xF0,(s->cset[pos]<<12)+eSPINTILE1,combobuf[s->data[pos]].o_tile+zc_max(1,combobuf[s->data[pos]].frames));
21496 }
21497
21498
21499 // It stands for next_side_pos
21500 50 void nsp(bool random)
21501 // moves sle_x and sle_y to the next position
21502 {
21503
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 if(random)
21504 {
21505 if(zc_oldrand()%2)
21506 {
21507 sle_x = (zc_oldrand()%2) ? 0 : 240;
21508 sle_y = (zc_oldrand()%10)*16;
21509 }
21510 else
21511 {
21512 sle_y = (zc_oldrand()%2) ? 0 : 160;
21513 sle_x = (zc_oldrand()%15)*16;
21514 }
21515
21516 return;
21517 }
21518
21519
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 22 times.
50 if(sle_x==0)
21520 {
21521
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 2 times.
22 if(sle_y<160)
21522 20 sle_y+=16;
21523 else
21524 2 sle_x+=16;
21525 22 }
21526
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 4 times.
28 else if(sle_y==160)
21527 {
21528
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 1 times.
24 if(sle_x<240)
21529 23 sle_x+=16;
21530 else
21531 1 sle_y-=16;
21532 24 }
21533
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 else if(sle_x==240)
21534 {
21535
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(sle_y>0)
21536 4 sle_y-=16;
21537 else
21538 sle_x-=16;
21539 4 }
21540 else if(sle_y==0)
21541 {
21542 if(sle_x>0)
21543 sle_x-=16;
21544 else
21545 sle_y+=16;
21546 }
21547 50 }
21548
21549 13 int32_t next_side_pos(bool random)
21550 // moves sle_x and sle_y to the next available position
21551 // returns the direction the enemy should face
21552 {
21553 bool blocked;
21554 13 int32_t c=0;
21555
21556 13 do
21557 {
21558
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 nsp(c>35 ? false : random);
21559
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
63 blocked = _walkflag(sle_x,sle_y,2) || _walkflag(sle_x,sle_y+8,2) ||
21560
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 (combo_class_buf[COMBOTYPE(sle_x,sle_y)].block_enemies ||
21561
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 MAPFLAG(sle_x,sle_y) == mfNOENEMY || MAPCOMBOFLAG(sle_x,sle_y)==mfNOENEMY ||
21562
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
13 MAPFLAG(sle_x,sle_y) == mfNOGROUNDENEMY || MAPCOMBOFLAG(sle_x,sle_y)==mfNOGROUNDENEMY ||
21563 13 iswaterex(MAPCOMBO(sle_x,sle_y), currmap, currscr, -1, sle_x, sle_y, true));
21564
21565
1/2
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
50 if(++c>50)
21566 return -1;
21567
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 13 times.
50 }
21568 50 while(blocked);
21569
21570 13 int32_t dir=0;
21571
21572
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4 times.
13 if(sle_x==0) dir=right;
21573
21574
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if(sle_y==0) dir=down;
21575
21576
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 4 times.
13 if(sle_x==240) dir=left;
21577
21578
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if(sle_y==168) dir=up;
21579
21580 13 return dir;
21581 13 }
21582
21583 bool can_side_load(int32_t id)
21584 {
21585 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
21586 {
21587 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "can_side_load()");
21588 return false;
21589 }
21590 switch(guysbuf[id].family) //id&0x0FFF)
21591 {
21592 //case eTEK1:
21593 //case eTEK2:
21594 //case eTEK3:
21595 //case eLEV1:
21596 //case eLEV2:
21597 //case eLEV3:
21598 //case eRAQUAM:
21599 //case eLAQUAM:
21600 //case eDODONGO:
21601 //case eMANHAN:
21602 //case eGLEEOK1:
21603 //case eGLEEOK2:
21604 //case eGLEEOK3:
21605 //case eGLEEOK4:
21606 //case eDIG1:
21607 //case eDIG3:
21608 //case eGOHMA1:
21609 //case eGOHMA2:
21610 //case eCENT1:
21611 //case eCENT2:
21612 //case ePATRA1:
21613 //case ePATRA2:
21614 //case eGANON:
21615 //case eMANHAN2:
21616 //case eCEILINGM: later
21617 //case eFLOORM: later
21618 //case ePATRABS:
21619 //case ePATRAL2:
21620 //case ePATRAL3:
21621 //case eGLEEOK1F:
21622 //case eGLEEOK2F:
21623 //case eGLEEOK3F:
21624 //case eGLEEOK4F:
21625 //case eDODONGOBS:
21626 //case eDODONGOF:
21627 //case eGOHMA3:
21628 //case eGOHMA4:
21629 //case eSHOOTMAGIC:
21630 //case eSHOOTROCK:
21631 //case eSHOOTSPEAR:
21632 //case eSHOOTSWORD:
21633 //case eSHOOTFLAME:
21634 //case eSHOOTFLAME2:
21635 //case eSHOOTFBALL:
21636 case eeTEK:
21637 case eeLEV:
21638 case eeAQUA:
21639 case eeDONGO:
21640 case eeMANHAN:
21641 case eeGLEEOK:
21642 case eeDIG:
21643 case eeGHOMA:
21644 case eeLANM:
21645 case eePATRA:
21646 case eeGANON:
21647 case eePROJECTILE:
21648 return false;
21649 break;
21650 }
21651
21652 return true;
21653 }
21654
21655 static bool script_sle = false;
21656 static int32_t sle_pattern = 0;
21657 void script_side_load_enemies()
21658 {
21659 if(script_sle || sle_clk) return;
21660 sle_cnt = 0;
21661 while(sle_cnt<10 && tmpscr->enemy[sle_cnt]!=0)
21662 ++sle_cnt;
21663 script_sle = true;
21664 sle_pattern = tmpscr->pattern;
21665 sle_clk = 0;
21666 }
21667
21668 295 void side_load_enemies()
21669 {
21670
3/4
✓ Branch 0 taken 295 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 292 times.
✓ Branch 3 taken 3 times.
295 if(!script_sle && sle_clk==0)
21671 {
21672 3 sle_pattern = tmpscr->pattern;
21673 3 sle_cnt = 0;
21674 3 int32_t guycnt = 0;
21675 3 int16_t s = (currmap<<7)+currscr;
21676 3 bool beenhere=false;
21677 3 bool reload=true;
21678 3 bool unbeatablereload = true;
21679
21680 3 load_default_enemies();
21681
21682
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 3 times.
21 for(int32_t i=0; i<6; i++)
21683
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if(visited[i]==s)
21684 beenhere=true;
21685
21686
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(!beenhere)
21687 {
21688 3 visited[vhead]=s;
21689 3 vhead = (vhead+1)%6;
21690 3 }
21691 else if(game->guys[s]==0)
21692 {
21693 sle_cnt=0;
21694 reload=false;
21695 }
21696
21697
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(reload)
21698 {
21699 3 sle_cnt = game->guys[s];
21700
21701
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if((get_bit(quest_rules, qr_NO_LEAVE_ONE_ENEMY_ALIVE_TRICK) && !beenhere)
21702
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
3 || sle_cnt==0)
21703 {
21704
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 3 times.
15 while(sle_cnt<10 && tmpscr->enemy[sle_cnt]!=0)
21705 12 ++sle_cnt;
21706 3 }
21707
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if (!beenhere && get_bit(quest_rules, qr_UNBEATABLES_DONT_KEEP_DEAD))
21708 {
21709 for(int32_t i = 0; i<sle_cnt && tmpscr->enemy[i]>0; i++)
21710 {
21711 if (!(guysbuf[tmpscr->enemy[i]].flags & guy_doesntcount))
21712 {
21713 unbeatablereload = false;
21714 }
21715 }
21716 if (unbeatablereload)
21717 {
21718 while(sle_cnt<10 && tmpscr->enemy[sle_cnt]!=0)
21719 {
21720 ++sle_cnt;
21721 }
21722 }
21723 }
21724 3 }
21725
21726
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if((get_bit(quest_rules,qr_ALWAYSRET)) || (tmpscr->flags3&fENEMIESRETURN))
21727 {
21728 sle_cnt = 0;
21729
21730 while(sle_cnt<10 && tmpscr->enemy[sle_cnt]!=0)
21731 ++sle_cnt;
21732 }
21733
21734
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 3 times.
15 for(int32_t i=0; i<sle_cnt; i++)
21735 12 ++guycnt;
21736
21737 3 game->guys[s] = guycnt;
21738 3 }
21739
21740
2/2
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 13 times.
295 if((++sle_clk+8)%24 == 0)
21741 {
21742 13 int32_t dir = next_side_pos(sle_pattern==pSIDESR);
21743
21744
3/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 11 times.
13 if(dir==-1 || tooclose(sle_x,sle_y,32))
21745 {
21746 2 return;
21747 }
21748
21749 11 int32_t enemy_slot=guys.Count();
21750
21751
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 while(sle_cnt > 0 && !ok2add(tmpscr->enemy[sle_cnt-1]))
21752 sle_cnt--;
21753
21754
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if(sle_cnt > 0)
21755 {
21756
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if(addenemy(sle_x,sle_y,tmpscr->enemy[--sle_cnt],0))
21757 {
21758
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (((enemy*)guys.spr(enemy_slot))->family != eeTEK)
21759 {
21760 11 guys.spr(enemy_slot)->dir = dir;
21761 11 }
21762 11 }
21763 11 }
21764 11 }
21765
21766
2/2
✓ Branch 0 taken 291 times.
✓ Branch 1 taken 2 times.
293 if(sle_cnt<=0)
21767 {
21768
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(script_sle)
21769 script_sle = false;
21770 2 else loaded_enemies=true;
21771 2 sle_clk = 0;
21772 2 }
21773 295 }
21774
21775 1902 bool is_starting_pos(int32_t i, int32_t x, int32_t y, int32_t t)
21776 {
21777
21778
4/4
✓ Branch 0 taken 1740 times.
✓ Branch 1 taken 162 times.
✓ Branch 2 taken 162 times.
✓ Branch 3 taken 1902 times.
1902 if(tmpscr->enemy[i]<1||tmpscr->enemy[i]>=MAXGUYS) //Hackish fix for crash in Waterford.st on screen 0x65 of dmap 0 (map 1).
21779 {
21780 //zprint2("is_starting_pos(), tmpscr->enemy[i] is: %d\n", tmpscr->enemy[i]);
21781 324 return false; //never 0, never OoB.
21782 }
21783 // No corner enemies
21784
6/6
✓ Branch 0 taken 1641 times.
✓ Branch 1 taken 261 times.
✓ Branch 2 taken 63 times.
✓ Branch 3 taken 1704 times.
✓ Branch 4 taken 180 times.
✓ Branch 5 taken 144 times.
1902 if((x==0 || x==240) && (y==0 || y==160))
21785
21786 324 return false;
21787
21788 //Is a no spawn combo...
21789
2/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1704 times.
1704 if(MAPFLAG(x+8,y+8)==mfNOENEMYSPAWN || MAPCOMBOFLAG(x+8,y+8)==mfNOENEMYSPAWN)
21790 return false;
21791
21792 // No enemies in dungeon walls
21793
6/10
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 1645 times.
✓ Branch 2 taken 59 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 59 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 59 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 59 times.
1704 if(isdungeon() && (x<32 || x>=224 || y<32 || y>=144))
21794 return false;
21795
21796 // Too close
21797
3/4
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 1568 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 136 times.
1704 if(tooclose(x,y,40) && t<11)
21798 136 return false;
21799
21800 // Can't fly onto it?
21801
3/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 1549 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
1570 if(isflier(tmpscr->enemy[i])&&
21802
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 (flyerblocked(x+8,y+8,spw_floater,guysbuf[tmpscr->enemy[i]])||
21803
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 17 times.
19 (_walkflag(x,y+8,2)&&!get_bit(quest_rules,qr_WALLFLIERS))))
21804 2 return false;
21805
21806 // Can't jump onto it?
21807 if
21808 (
21809
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
1574 guysbuf[tmpscr->enemy[i]].family==eeTEK
21810
21811
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1558 times.
1566 &&
21812 (
21813
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 COMBOTYPE(x+8,y+8)==cNOJUMPZONE||
21814
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 COMBOTYPE(x+8,y+8)==cNOENEMY||
21815
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 ispitfall(x+8,y+8)||
21816
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 MAPFLAG(x+8,y+8)==mfNOENEMY||
21817 8 MAPCOMBOFLAG(x+8,y+8)==mfNOENEMY
21818 )
21819 )
21820 {
21821 return false;
21822 }
21823
21824 // Other off-limit combos
21825
6/6
✓ Branch 0 taken 1549 times.
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 1541 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 1193 times.
✓ Branch 5 taken 348 times.
3107 if((!isflier(tmpscr->enemy[i])&& guysbuf[tmpscr->enemy[i]].family!=eeTEK &&
21826
2/2
✓ Branch 0 taken 1197 times.
✓ Branch 1 taken 344 times.
1541 (_walkflag(x,y+8,2) || groundblocked(x+8,y+8,guysbuf[tmpscr->enemy[i]]))) &&
21827 1541 guysbuf[tmpscr->enemy[i]].family!=eeZORA)
21828 348 return false;
21829
21830 // Don't ever generate enemies on these combos!
21831
2/4
✓ Branch 0 taken 1218 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1218 times.
1218 if(COMBOTYPE(x+8,y+8)==cARMOS||COMBOTYPE(x+8,y+8)==cBSGRAVE)
21832 return false;
21833
21834 //BS Dodongos need at least 2 spaces.
21835
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1218 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1218 if((guysbuf[tmpscr->enemy[i]].family==eeDONGO)&&(guysbuf[tmpscr->enemy[i]].misc10==1))
21836 {
21837 if(((x<16) ||_walkflag(x-16,y+8, 2))&&
21838 ((x>224)||_walkflag(x+16,y+8, 2))&&
21839 ((y<16) ||_walkflag(x, y-8, 2))&&
21840 ((y>144)||_walkflag(x, y+24,2)))
21841 {
21842 return false;
21843 }
21844 }
21845
21846 1218 return true;
21847 1740 }
21848
21849 242 bool is_ceiling_pattern(int32_t i)
21850 {
21851
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 242 times.
242 return (i==pCEILING || i==pCEILINGR);
21852 }
21853
21854 9 int32_t placeenemy(int32_t i)
21855 {
21856 9 std::map<int32_t, int32_t> freeposcache;
21857 9 int32_t frees = 0;
21858
21859
2/2
✓ Branch 0 taken 99 times.
✓ Branch 1 taken 9 times.
108 for(int32_t y=0; y<176; y+=16)
21860 {
21861
2/2
✓ Branch 0 taken 1584 times.
✓ Branch 1 taken 99 times.
1683 for(int32_t x=0; x<256; x+=16)
21862 {
21863
3/4
✓ Branch 0 taken 1584 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1107 times.
✓ Branch 3 taken 477 times.
1584 if(is_starting_pos(i,x,y,0))
21864 {
21865
1/2
✓ Branch 0 taken 1107 times.
✗ Branch 1 not taken.
1107 freeposcache[frees++] = (y&0xF0)+(x>>4);
21866 1107 }
21867 1584 }
21868 99 }
21869
21870
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if(frees > 0)
21871
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 return freeposcache[zc_oldrand()%frees];
21872
21873 return -1;
21874 9 }
21875
21876 121 void spawnEnemy(int& pos, int& clk, int& x, int& y, int& fastguys, int& i, int& guycnt, int& loadcnt)
21877 {
21878 121 bool placed=false;
21879 121 int32_t t=-1;
21880
21881 // First: enemy combo flags
21882
2/2
✓ Branch 0 taken 1323 times.
✓ Branch 1 taken 120 times.
1443 for(int32_t sy=0; sy<176; sy+=16)
21883 {
21884
2/2
✓ Branch 0 taken 21161 times.
✓ Branch 1 taken 1322 times.
22483 for(int32_t sx=0; sx<256; sx+=16)
21885 {
21886 21161 int32_t cflag = MAPFLAG(sx, sy);
21887 21161 int32_t cflag_i = MAPCOMBOFLAG(sx, sy);
21888
21889
2/4
✓ Branch 0 taken 21161 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21161 times.
✗ Branch 3 not taken.
21161 if(((cflag==mfENEMYALL)||(cflag_i==mfENEMYALL)) && (!placed))
21890 {
21891 if(!ok2add(tmpscr->enemy[i]))
21892 {
21893 if (loadcnt < 10 && tmpscr->enemy[i] > 0 && tmpscr->enemy[i] < MAXGUYS) ++loadcnt;
21894 }
21895 else
21896 {
21897 addenemy(sx,
21898 (is_ceiling_pattern(tmpscr->pattern) && isSideViewGravity()) ? -(150+50*guycnt) : sy,
21899 (is_ceiling_pattern(tmpscr->pattern) && !(isSideViewGravity())) ? 150+50*guycnt : 0,tmpscr->enemy[i],-15);
21900
21901 ++guycnt;
21902
21903 placed=true;
21904 goto placed_enemy;
21905 }
21906 }
21907
21908
4/4
✓ Branch 0 taken 21160 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 21160 times.
✓ Branch 3 taken 1 times.
21161 else if(((cflag==mfENEMY0+i)||(cflag_i==mfENEMY0+i)) && (!placed))
21909 {
21910
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(!ok2add(tmpscr->enemy[i]))
21911 {
21912 if (loadcnt < 10 && tmpscr->enemy[i] > 0 && tmpscr->enemy[i] < MAXGUYS) ++loadcnt;
21913 }
21914 else
21915 {
21916 2 addenemy(sx,
21917
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 (is_ceiling_pattern(tmpscr->pattern) && isSideViewGravity()) ? -(150+50*guycnt) : sy,
21918
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 (is_ceiling_pattern(tmpscr->pattern) && !(isSideViewGravity())) ? 150+50*guycnt : 0,tmpscr->enemy[i],-15);
21919
21920 1 ++guycnt;
21921
21922 1 placed=true;
21923 1 goto placed_enemy;
21924 }
21925 }
21926 21160 }
21927 1322 }
21928
21929 // Next: enemy pattern
21930
5/8
✗ Branch 0 not taken.
✓ Branch 1 taken 120 times.
✓ Branch 2 taken 111 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 111 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 111 times.
120 if((tmpscr->pattern==pRANDOM || tmpscr->pattern==pCEILING) && !(isSideViewGravity()) && ((tmpscr->enemy[i]>0&&tmpscr->enemy[i]<MAXGUYS)))
21931 {
21932 111 do
21933 {
21934
21935 // NES positions
21936 156 pos%=9;
21937 156 x=stx[loadside][pos];
21938 156 y=sty[loadside][pos];
21939 156 ++pos;
21940 156 ++t;
21941
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 111 times.
267 }
21942
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 156 times.
156 while((t< 20) && !is_starting_pos(i,x,y,t));
21943 111 }
21944
21945
3/4
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 111 times.
120 if(t<0 || t >= 20) // above enemy pattern failed
21946 {
21947 // Final chance: find a random position anywhere onscreen
21948 9 int32_t randpos = placeenemy(i);
21949
21950
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if(randpos>-1)
21951 {
21952 9 x=(randpos&15)<<4;
21953 9 y= randpos&0xF0;
21954 9 }
21955 else // All opportunities failed - abort
21956 {
21957 return;
21958 }
21959 9 }
21960
21961 {
21962 120 int32_t c=0;
21963 120 c=clk;
21964
21965
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 58 times.
120 if(!slowguy(tmpscr->enemy[i]))
21966 58 ++fastguys;
21967
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
62 else if(fastguys>0)
21968 c=-15*(i-fastguys+2);
21969 else
21970 62 c=-15*(i+1);
21971
21972
4/6
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 82 times.
✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 38 times.
120 if(BSZ&&((tmpscr->enemy[i]>0&&tmpscr->enemy[i]<MAXGUYS))) // Hackish fix for crash in Waterford.qst on screen 0x65 of dmap 0 (map 1).
21973 {
21974 // Special case for blue leevers
21975
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
38 if(guysbuf[tmpscr->enemy[i]].family==eeLEV && guysbuf[tmpscr->enemy[i]].misc1==1)
21976 c=-15*(i+1);
21977 else
21978 38 c=-15;
21979 38 }
21980
21981
1/2
✓ Branch 0 taken 120 times.
✗ Branch 1 not taken.
120 if(!ok2add(tmpscr->enemy[i]))
21982 {
21983 if (loadcnt < 10 && tmpscr->enemy[i] > 0 && tmpscr->enemy[i] < MAXGUYS) ++loadcnt;
21984 }
21985 else
21986 {
21987
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 120 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
120 if(((tmpscr->enemy[i]>0||tmpscr->enemy[i]<MAXGUYS))) // Hackish fix for crash in Waterford.qst on screen 0x65 of dmap 0 (map 1).
21988 {
21989
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 120 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
240 addenemy(x,(is_ceiling_pattern(tmpscr->pattern) && isSideViewGravity()) ? -(150+50*guycnt) : y,
21990
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 120 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
120 (is_ceiling_pattern(tmpscr->pattern) && !(isSideViewGravity())) ? 150+50*guycnt : 0,tmpscr->enemy[i],c);
21991
21992 120 ++guycnt;
21993 120 }
21994 }
21995
21996 120 placed=true;
21997 120 } // if(t < 20)
21998
21999 placed_enemy:
22000
22001 // I don't like this, but it seems to work...
22002 static bool foundCarrier;
22003
22004
2/2
✓ Branch 0 taken 97 times.
✓ Branch 1 taken 24 times.
121 if(i==0)
22005 24 foundCarrier=false;
22006
22007
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 121 times.
121 if(placed)
22008 {
22009
3/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 97 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
121 if(i==0 && tmpscr->enemyflags&efLEADER)
22010 {
22011 int32_t index = guys.idFirst(tmpscr->enemy[i],0xFFF);
22012
22013 if(index!=-1)
22014 {
22015 //grab the first segment. Not accurate to how older versions did it, but the way they did it might be incompatible with enemy editor.
22016 if ((((enemy*)guys.spr(index))->family == eeLANM) && !get_bit(quest_rules, qr_NO_LANMOLA_RINGLEADER)) index = guys.idNth(tmpscr->enemy[i], 2, 0xFFF);
22017 if(index!=-1)
22018 {
22019 ((enemy*)guys.spr(index))->leader = true;
22020 }
22021 }
22022 }
22023
22024
4/4
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 116 times.
✓ Branch 3 taken 1 times.
121 if(!foundCarrier && hasitem&(4|2))
22025 {
22026 1 int32_t index = guys.idFirst(tmpscr->enemy[i],0xFFF);
22027
22028
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if(index!=-1 && (((enemy*)guys.spr(index))->flags&guy_doesntcount)==0)
22029 {
22030 1 ((enemy*)guys.spr(index))->itemguy = true;
22031 1 foundCarrier=true;
22032 1 }
22033 1 }
22034 121 }
22035 121 }
22036
22037 bool scriptloadenemies()
22038 {
22039 loaded_enemies = true;
22040 if(script_sle || sle_clk) return false;
22041 if(tmpscr->pattern==pNOSPAWN) return false;
22042
22043 if(tmpscr->pattern==pSIDES || tmpscr->pattern==pSIDESR)
22044 {
22045 script_side_load_enemies();
22046 return true;
22047 }
22048
22049 int32_t pos=zc_oldrand()%9;
22050 int32_t clk=-15,x=0,y=0,fastguys=0;
22051 int32_t i=0,guycnt=0;
22052 int32_t loadcnt = 10;
22053
22054 for(; i<loadcnt && tmpscr->enemy[i]>0; i++)
22055 {
22056 spawnEnemy(pos, clk, x, y, fastguys, i, guycnt, loadcnt);
22057
22058 --clk;
22059 }
22060 return true;
22061 }
22062
22063 24702 void loadenemies()
22064 {
22065
3/4
✓ Branch 0 taken 24702 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 292 times.
✓ Branch 3 taken 24410 times.
24702 if(script_sle || sle_clk)
22066 {
22067 292 side_load_enemies();
22068 292 return;
22069 }
22070
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24410 times.
24410 if(tmpscr->pattern==pNOSPAWN) return;
22071
2/2
✓ Branch 0 taken 24350 times.
✓ Branch 1 taken 60 times.
24410 if(loaded_enemies)
22072 24350 return;
22073
22074 // check if it's the dungeon boss and it has been beaten before
22075
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
60 if(tmpscr->enemyflags&efBOSS && game->lvlitems[dlevel]&liBOSS)
22076 {
22077 loaded_enemies = true;
22078 return;
22079 }
22080
22081
3/4
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 57 times.
60 if(tmpscr->pattern==pSIDES || tmpscr->pattern==pSIDESR)
22082 {
22083 3 side_load_enemies();
22084 3 return;
22085 }
22086
22087 57 loaded_enemies=true;
22088
22089 // do enemies that are always loaded
22090 57 load_default_enemies();
22091
22092 // dungeon basements
22093
22094 static byte dngn_enemy_x[4] = {32,96,144,208};
22095
22096
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 54 times.
57 if(currscr>=128)
22097 {
22098
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(DMaps[currdmap].flags&dmfCAVES) return;
22099 if ( DMaps[currdmap].flags&dmfNEWCELLARENEMIES )
22100 {
22101 for(int32_t i=0; i<10; i++)
22102 {
22103 if ( tmpscr->enemy[i] )
22104 {
22105 addenemy(dngn_enemy_x[i],96,tmpscr->enemy[i],-14-i);
22106 }
22107 }
22108 }
22109 else
22110 {
22111 for(int32_t i=0; i<4; i++)
22112 addenemy(dngn_enemy_x[i],96,tmpscr->enemy[i]?tmpscr->enemy[i]:(int32_t)eKEESE1,-14-i);
22113 }
22114 return;
22115 }
22116
22117 // check if it's been long enough to reload all enemies
22118
22119 54 int32_t loadcnt = 10;
22120 54 int16_t s = (currmap<<7)+currscr;
22121 54 bool beenhere = false;
22122 54 bool reload = true;
22123 54 bool unbeatablereload = true;
22124
22125
2/2
✓ Branch 0 taken 324 times.
✓ Branch 1 taken 54 times.
378 for(int32_t i=0; i<6; i++)
22126
2/2
✓ Branch 0 taken 312 times.
✓ Branch 1 taken 12 times.
336 if(visited[i]==s)
22127 12 beenhere = true;
22128
22129
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 42 times.
54 if(!beenhere) //Okay so this basically checks the last 6 unique screen's you've been in and checks if the current screen is one of them.
22130 {
22131 42 visited[vhead]=s; //If not, it adds it to the array,
22132 42 vhead = (vhead+1)%6; //which overrides one of the others, and then moves onto the next.
22133 42 }
22134
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 11 times.
12 else if(game->guys[s]==0) //Then, if you have been here, and the number of enemies left on the screen is 0,
22135 {
22136 11 loadcnt = 0; //It will tell it not to load any enemies,
22137 11 reload = false; //both by setting loadcnt to 0 and making the reload if statement not run.
22138 11 }
22139
22140
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 43 times.
54 if(reload) //This if statement is only false if this screen is one of the last 6 screens you visited and you left 0 enemies alive.
22141 {
22142 43 loadcnt = game->guys[s]; //Otherwise, if this if statement is true, it will try to load the last amount of enemies you left alive.
22143
22144
2/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
43 if(loadcnt==0 || //Then, if the number of enemies is 0, that means you left 0 enemies alive on a screen but haven't been there in the past 6 screens.
22145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 (get_bit(quest_rules, qr_NO_LEAVE_ONE_ENEMY_ALIVE_TRICK) && !beenhere)) //Alternatively, if you have the quest rule enabled that always respawns all enemies after a period of time, and you haven't been here in 6 screens.
22146 42 loadcnt = 10; //That means all enemies need to be respawned.
22147
3/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 42 times.
✗ Branch 3 not taken.
43 if (!beenhere && get_bit(quest_rules, qr_UNBEATABLES_DONT_KEEP_DEAD))
22148 {
22149 for(int32_t i = 0; i<loadcnt && tmpscr->enemy[i]>0; i++)
22150 {
22151 if (!(guysbuf[tmpscr->enemy[i]].flags & guy_doesntcount))
22152 {
22153 unbeatablereload = false;
22154 }
22155 }
22156 if (unbeatablereload)
22157 {
22158 loadcnt = 10;
22159 }
22160 }
22161 43 }
22162
22163
2/4
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 54 times.
54 if((get_bit(quest_rules,qr_ALWAYSRET)) || (tmpscr->flags3&fENEMIESRETURN)) //If enemies always return is enabled quest-wide or for this screen,
22164 loadcnt = 10; //All enemies also need to be respawned.
22165
22166 54 int32_t pos=zc_oldrand()%9; //This sets up a variable for spawnEnemy to edit so as to spawn the enemies pseudo-randomly.
22167 54 int32_t clk=-15,x=0,y=0,fastguys=0; //clk being negative means the enemy is in it's spawn poof.
22168 54 int32_t i=0,guycnt=0; //Lastly, resets guycnt to 0 so spawnEnemy can increment it manually per-enemy.
22169
22170
4/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 161 times.
✓ Branch 2 taken 121 times.
✓ Branch 3 taken 54 times.
175 for(; i<loadcnt && tmpscr->enemy[i]>0; i++)
22171 {
22172 121 spawnEnemy(pos, clk, x, y, fastguys, i, guycnt, loadcnt);
22173
22174 121 --clk; //Each additional enemy spawns with a slightly longer spawn poof than the previous.
22175 121 }
22176
22177 54 game->guys[s] = guycnt;
22178 //} //if(true)
22179 24702 }
22180 void moneysign()
22181 {
22182 additem(48,108,iRupy,ipDUMMY);
22183 // textout(scrollbuf,zfont,"X",64,112,CSET(0)+1);
22184 set_clip_state(pricesdisplaybuf, 0);
22185 textout_ex(pricesdisplaybuf,zfont,"X",64,112,CSET(0)+1,-1);
22186 }
22187
22188 4 void putprices(bool sign)
22189 {
22190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(fadeclk > 0) return;
22191 // refresh what's under the prices
22192 // for(int32_t i=5; i<12; i++)
22193 // putcombo(scrollbuf,i<<4,112,tmpscr->data[112+i],tmpscr->cpage);
22194
22195 4 rectfill(pricesdisplaybuf, 72, 112, pricesdisplaybuf->w-1, pricesdisplaybuf->h-1, 0);
22196 4 int32_t step=32;
22197 4 int32_t x=80;
22198
22199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(prices[2]==0)
22200 {
22201 4 step<<=1;
22202
22203
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(prices[1]==0)
22204 {
22205 4 x=112;
22206 4 }
22207 4 }
22208
22209
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 12 times.
16 for(int32_t i=0; i<3; i++)
22210 {
22211 // Kind of stupid, but it works: 100000 is used to indicate that an item
22212 // has a price of zero rather than there being no item.
22213 // 100000 isn't a valid price, so this doesn't cause problems.
22214
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if(prices[i]!=0 && prices[i]<100000)
22215 {
22216 char buf[8];
22217 sprintf(buf,sign?"%+3d":"%3d",prices[i]);
22218
22219 int32_t l=(int32_t)strlen(buf);
22220 set_clip_state(pricesdisplaybuf, 0);
22221 textout_ex(pricesdisplaybuf,zfont,buf,x-(l>3?(l-3)<<3:0),112,CSET(0)+1,-1);
22222 }
22223
22224 12 x+=step;
22225 12 }
22226 4 }
22227
22228 // Setting up special rooms
22229 // Also called when the Letter is used successfully.
22230 4 void setupscreen()
22231 {
22232 4 boughtsomething=false;
22233 4 int32_t t=currscr<128?0:1;
22234 4 word str=tmpscr[t].str;
22235
22236 // Prices are already set to 0 in dowarp()
22237
2/15
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
4 switch(tmpscr[t].room)
22238 {
22239 case rSP_ITEM: // special item
22240 3 additem(120,89,tmpscr[t].catchall,ipONETIME2+ipHOLDUP+ipCHECK | ((tmpscr->flags8&fITEMSECRET) ? ipSECRETS : 0));
22241 3 break;
22242
22243 case rINFO: // pay for info
22244 {
22245 int32_t count = 0;
22246 int32_t base = 88;
22247 int32_t step = 5;
22248
22249 moneysign();
22250
22251 for(int32_t i=0; i<3; i++)
22252 {
22253 if(QMisc.info[tmpscr[t].catchall].str[i])
22254 {
22255 ++count;
22256 }
22257 else
22258 break;
22259 }
22260
22261 if(count)
22262 {
22263 if(count==1)
22264 {
22265 base = 88+32;
22266 }
22267
22268 if(count==2)
22269 {
22270 step = 6;
22271 }
22272
22273 for(int32_t i=0; i < count; i++)
22274 {
22275 additem((i << step)+base, 89, iRupy, ipMONEY + ipDUMMY);
22276 ((item*)items.spr(items.Count()-1))->PriceIndex = i;
22277 prices[i] = -(QMisc.info[tmpscr[t].catchall].price[i]);
22278 if(prices[i]==0)
22279 prices[i]=100000; // So putprices() knows there's an item here and positions the price correctly
22280 int32_t itemid = current_item_id(itype_wealthmedal);
22281
22282 if(itemid>=0 && prices[i]!=100000)
22283 {
22284 if(itemsbuf[itemid].flags & ITEM_FLAG1)
22285 prices[i]=((prices[i]*itemsbuf[itemid].misc1)/100);
22286 else
22287 prices[i]-=itemsbuf[itemid].misc1;
22288 prices[i]=vbound(prices[i], -99999, 0);
22289 if(prices[i]==0)
22290 prices[i]=100000;
22291 }
22292
22293 if((QMisc.info[tmpscr[t].catchall].price[i])>1 && prices[i]>-1 && prices[i]!=100000)
22294 prices[i]=-1;
22295 }
22296 }
22297
22298 break;
22299 }
22300
22301 case rMONEY: // secret money
22302 additem(120,89,iRupy,ipONETIME+ipDUMMY+ipMONEY);
22303 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22304 break;
22305
22306 case rGAMBLE: // gambling
22307 prices[0]=prices[1]=prices[2]=-10;
22308 moneysign();
22309 additem(88,89,iRupy,ipMONEY+ipDUMMY);
22310 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22311 additem(120,89,iRupy,ipMONEY+ipDUMMY);
22312 ((item*)items.spr(items.Count()-1))->PriceIndex = 1;
22313 additem(152,89,iRupy,ipMONEY+ipDUMMY);
22314 ((item*)items.spr(items.Count()-1))->PriceIndex = 2;
22315 break;
22316
22317 case rREPAIR: // door repair
22318 setmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM);
22319 // }
22320 repaircharge=tmpscr[t].catchall;
22321 break;
22322
22323 case rMUPGRADE: // upgrade magic
22324 adjustmagic=true;
22325 break;
22326
22327 case rLEARNSLASH: // learn slash attack
22328 learnslash=true;
22329 break;
22330
22331 case rRP_HC: // heart container or red potion
22332 additem(88,89,iRPotion,ipONETIME2+ipHOLDUP+ipFADE);
22333 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22334 additem(152,89,iHeartC,ipONETIME2+ipHOLDUP+ipFADE);
22335 ((item*)items.spr(items.Count()-1))->PriceIndex = 1;
22336 break;
22337
22338 case rP_SHOP: // potion shop
22339 if(current_item(itype_letter)<i_letter_used)
22340 {
22341 str=0;
22342 break;
22343 }
22344
22345 [[fallthrough]];
22346 case rTAKEONE: // take one
22347 case rSHOP: // shop
22348 {
22349 int32_t count = 0;
22350 int32_t base = 88;
22351 int32_t step = 5;
22352
22353 if(tmpscr[t].room != rTAKEONE)
22354 moneysign();
22355
22356 //count and align the stuff
22357 for(int32_t i=0; i<3; ++i)
22358 {
22359 if(QMisc.shop[tmpscr[t].catchall].hasitem[count] != 0)
22360 {
22361 ++count;
22362 }
22363 else
22364 {
22365 break;
22366 }
22367 }
22368
22369 if(count==1)
22370 {
22371 base = 88+32;
22372 }
22373
22374 if(count==2)
22375 {
22376 step = 6;
22377 }
22378
22379 for(int32_t i=0; i<count; i++)
22380 {
22381 additem((i<<step)+base, 89, QMisc.shop[tmpscr[t].catchall].item[i], ipHOLDUP+ipFADE+(tmpscr[t].room == rTAKEONE ? ipONETIME2 : ipCHECK));
22382 ((item*)items.spr(items.Count()-1))->PriceIndex = i;
22383
22384 if(tmpscr[t].room != rTAKEONE)
22385 {
22386 prices[i] = QMisc.shop[tmpscr[t].catchall].price[i];
22387 if(prices[i]==0)
22388 prices[i]=100000; // So putprices() knows there's an item here and positions the price correctly
22389 int32_t itemid = current_item_id(itype_wealthmedal);
22390
22391 if(itemid>=0 && prices[i]!=100000)
22392 {
22393 if(itemsbuf[itemid].flags & ITEM_FLAG1)
22394 prices[i]=((prices[i]*itemsbuf[itemid].misc1)/100);
22395 else
22396 prices[i]+=itemsbuf[itemid].misc1;
22397 prices[i]=vbound(prices[i], 0, 99999);
22398 if(prices[i]==0)
22399 prices[i]=100000;
22400 }
22401
22402 if((QMisc.shop[tmpscr[t].catchall].price[i])>1 && prices[i]<1)
22403 prices[i]=1;
22404 }
22405 }
22406
22407 break;
22408 }
22409 case rBOTTLESHOP: // bottle shop
22410 {
22411 int32_t count = 0;
22412 int32_t base = 88;
22413 int32_t step = 5;
22414
22415 moneysign();
22416 bottleshoptype const& bst = QMisc.bottle_shop_types[tmpscr[t].catchall];
22417 //count and align the stuff
22418 for(int32_t i=0; i<3; ++i)
22419 {
22420 if(bst.fill[count] != 0)
22421 {
22422 ++count;
22423 }
22424 else
22425 {
22426 break;
22427 }
22428 }
22429
22430 if(count==1)
22431 {
22432 base = 88+32;
22433 }
22434
22435 if(count==2)
22436 {
22437 step = 6;
22438 }
22439
22440 for(int32_t i=0; i<count; i++)
22441 {
22442 adddummyitem((i<<step)+base, 89, /*Use item 0 as a dummy...*/0, ipHOLDUP+ipFADE+ipCHECK);
22443 //{ Setup dummy item
22444 item* curItem = ((item*)items.spr(items.Count()-1));
22445 curItem->PriceIndex = i;
22446 newcombo const& cmb = combobuf[bst.comb[i]];
22447 curItem->o_tile = cmb.o_tile;
22448 curItem->o_cset = bst.cset[i];
22449 curItem->cs = curItem->o_cset;
22450 curItem->tile = cmb.o_tile;
22451 curItem->o_speed = cmb.speed;
22452 curItem->o_delay = 0;
22453 curItem->frames = cmb.frames;
22454 curItem->flip = cmb.flip;
22455 curItem->family = itype_bottlefill; //no pickup w/o empty bottle
22456 curItem->pstring = 0;
22457 curItem->pickup = ipHOLDUP+ipFADE+ipCHECK;
22458 curItem->flash = false;
22459 curItem->twohand = false;
22460 curItem->anim = true;
22461 curItem->hxsz=1;
22462 curItem->hyofs=4;
22463 curItem->hysz=12;
22464 curItem->script=0;
22465 curItem->txsz=1;
22466 curItem->tysz=1;
22467 //}
22468
22469 prices[i] = bst.price[i];
22470 if(prices[i]==0)
22471 prices[i]=100000; // So putprices() knows there's an item here and positions the price correctly
22472 int32_t itemid = current_item_id(itype_wealthmedal);
22473
22474 if(itemid>=0 && prices[i]!=100000)
22475 {
22476 if(itemsbuf[itemid].flags & ITEM_FLAG1)
22477 prices[i]=((prices[i]*itemsbuf[itemid].misc1)/100);
22478 else
22479 prices[i]+=itemsbuf[itemid].misc1;
22480 prices[i]=vbound(prices[i], 0, 99999);
22481 if(prices[i]==0)
22482 prices[i]=100000;
22483 }
22484
22485 if((bst.price[i])>1 && prices[i]<1)
22486 prices[i]=1;
22487 }
22488
22489 break;
22490 }
22491
22492 case rBOMBS: // more bombs
22493 additem(120,89,iRupy,ipDUMMY+ipMONEY);
22494 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22495 prices[0]=-tmpscr[t].catchall;
22496 break;
22497
22498 case rARROWS: // more arrows
22499 additem(120,89,iRupy,ipDUMMY+ipMONEY);
22500 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22501 prices[0]=-tmpscr[t].catchall;
22502 break;
22503
22504 case rSWINDLE: // leave heart container or money
22505 additem(88,89,iHeartC,ipDUMMY+ipMONEY);
22506 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22507 prices[0]=-1;
22508 additem(152,89,iRupy,ipDUMMY+ipMONEY);
22509 ((item*)items.spr(items.Count()-1))->PriceIndex = 1;
22510 prices[1]=-tmpscr[t].catchall;
22511 break;
22512
22513 }
22514
22515
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if(tmpscr[t].room == rBOMBS || tmpscr[t].room == rARROWS)
22516 {
22517 int32_t i = (tmpscr[t].room == rSWINDLE ? 1 : 0);
22518 int32_t itemid = current_item_id(itype_wealthmedal);
22519
22520 if(itemid >= 0)
22521 {
22522 if(itemsbuf[itemid].flags & ITEM_FLAG1)
22523 prices[i]*=(itemsbuf[itemid].misc1/100.0);
22524 else
22525 prices[i]+=itemsbuf[itemid].misc1;
22526 }
22527
22528 if(tmpscr[t].catchall>1 && prices[i]>-1)
22529 prices[i]=-1;
22530 }
22531
22532 4 putprices(false);
22533
22534
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(str)
22535 {
22536 4 donewmsg(str);
22537 4 }
22538 else
22539 {
22540 Hero.unfreeze();
22541 }
22542 4 }
22543
22544 // Increments msgptr and returns the control code argument pointed at.
22545 word grab_next_argument()
22546 {
22547 if(unsigned(msgptr+1)>=MsgStrings[msgstr].s.size()) return 0;
22548 byte val=MsgStrings[msgstr].s[++msgptr]-1;
22549 word ret=val;
22550
22551 // If an argument is succeeded by 255, then it's a three-byte argument -
22552 // between 254 and 65535 (or whatever the maximum actually is)
22553 if((unsigned(msgptr+2)<MsgStrings[msgstr].s.size())
22554 && uint8_t(MsgStrings[msgstr].s[msgptr+1]) == 255)
22555 {
22556 val=MsgStrings[msgstr].s[msgptr+2];
22557 word next=val;
22558 ret += 254*next;
22559 msgptr+=2;
22560 }
22561
22562 return ret;
22563 }
22564
22565 enum
22566 {
22567 MNU_CURSOR_TILE, MNU_CURSOR_CSET,
22568 MNU_CURSOR_WID, MNU_CURSOR_HEI, MNU_CURSOR_FLIP,
22569
22570 MNU_CHOSEN, MNU_TIMER, MNU_CAN_CONFIRM,
22571
22572 MNU_DATA_MAX
22573 };
22574 struct menu_choice
22575 {
22576 int32_t x, y;
22577 int32_t pos;
22578 int32_t upos, dpos, lpos, rpos;
22579 menu_choice() : x(0), y(0), pos(0), upos(0), dpos(0), lpos(0), rpos(0)
22580 {}
22581 menu_choice(int32_t x, int32_t y, int32_t pos, int32_t upos,
22582 int32_t dpos, int32_t lpos, int32_t rpos)
22583 : x(x), y(y), pos(pos), upos(upos), dpos(dpos), lpos(lpos), rpos(rpos)
22584 {}
22585 };
22586 static int32_t msg_menu_data[MNU_DATA_MAX];
22587 static bool do_run_menu = false;
22588 bool do_end_str = false;
22589 static bool wait_advance = false;
22590 6 static std::map<int32_t, menu_choice> menu_options;
22591 69 void clr_msg_data()
22592 {
22593 69 do_end_str = false;
22594 69 wait_advance = false;
22595 69 do_run_menu = false;
22596 69 menu_options.clear();
22597 69 memset(msg_menu_data, 0, sizeof(msg_menu_data));
22598 69 }
22599
22600 static bool doing_name_insert = false;
22601 static char namebuf[9] = {0};
22602 static char* nameptr = NULL;
22603 static int32_t ssc_tile_hei = -1, ssc_tile_hei_buf = -1;
22604 bool runMenuCursor()
22605 {
22606 clear_bitmap(msg_menu_bmp_buf);
22607 if(!menu_options.size())
22608 {
22609 msg_menu_data[MNU_CHOSEN] = 0;
22610 return true; //end menu
22611 }
22612 int32_t pos = msg_menu_data[MNU_CHOSEN];
22613 //If the cursor is at an invalid pos, find the first pos >= 0...
22614 if(menu_options.find(pos) == menu_options.end())
22615 {
22616 pos = 0;
22617 while(menu_options.find(pos) == menu_options.end())
22618 ++pos;
22619 }
22620 menu_choice* ch = &menu_options[pos];
22621
22622 bool pressed = true;
22623 if(rUp()) pos = ch->upos;
22624 else if(rDown()) pos = ch->dpos;
22625 else if(rLeft()) pos = ch->lpos;
22626 else if(rRight()) pos = ch->rpos;
22627 else pressed = false;
22628
22629 if(pressed)
22630 msg_menu_data[MNU_TIMER] = 1;
22631
22632 bool hold_input = !((msg_menu_data[MNU_TIMER]++) % 5);
22633 bool held = false;
22634 if(hold_input)
22635 {
22636 held = true;
22637 if(Up()) pos = ch->upos;
22638 else if(Down()) pos = ch->dpos;
22639 else if(Left()) pos = ch->lpos;
22640 else if(Right()) pos = ch->rpos;
22641 else held = false;
22642 }
22643 //If the cursor is at an invalid pos, find the first pos >= 0...
22644 if(menu_options.find(pos) == menu_options.end())
22645 {
22646 pos = 0;
22647 while(menu_options.find(pos) == menu_options.end())
22648 ++pos;
22649 }
22650 if((pressed || held) && pos != msg_menu_data[MNU_CHOSEN])
22651 sfx(MsgStrings[msgstr].sfx);
22652
22653 ch = &menu_options[pos];
22654 overtileblock16(msg_menu_bmp_buf, msg_menu_data[MNU_CURSOR_TILE],
22655 ch->x, ch->y, (int32_t)ceil(msg_menu_data[MNU_CURSOR_WID]/16.0),
22656 (int32_t)ceil(msg_menu_data[MNU_CURSOR_HEI]/16.0),
22657 msg_menu_data[MNU_CURSOR_CSET], msg_menu_data[MNU_CURSOR_FLIP]);
22658
22659 msg_menu_data[MNU_CHOSEN] = pos;
22660
22661 if(!msg_menu_data[MNU_CAN_CONFIRM]) //Prevent instantly accepting when holding A
22662 {
22663 rAbtn(); //Eat
22664 if(!cAbtn()) msg_menu_data[MNU_CAN_CONFIRM] = 1;
22665 }
22666
22667 bool ret = (pressed || held) ? false : rAbtn();
22668 //Eat inputs
22669 rUp(); rDown(); rLeft(); rRight(); rAbtn();
22670
22671 if(ret)
22672 menu_options.clear();
22673
22674 return ret;
22675 //false if pos changed this frame; no confirming while moving the cursor!
22676 }
22677
22678 1156 bool bottom_margin_clip()
22679 {
22680 1156 return !get_bit(quest_rules, qr_OLD_STRING_EDITOR_MARGINS)
22681
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1156 times.
1156 && cursor_y >= (msg_h + (get_bit(quest_rules,qr_STRING_FRAME_OLD_WIDTH_HEIGHT)?16:0) - msg_margins[down]);
22682 }
22683
22684 148 bool parsemsgcode()
22685 {
22686
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 144 times.
148 if(msgptr>=MsgStrings[msgstr].s.size()) return false;
22687 144 byte c = byte(MsgStrings[msgstr].s[msgptr]-1);
22688
1/36
✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
144 switch(c)
22689 {
22690 case MSGC_NEWLINE:
22691 {
22692 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
22693 ssc_tile_hei = ssc_tile_hei_buf;
22694 ssc_tile_hei_buf = -1;
22695 cursor_y += thei + MsgStrings[msgstr].vspace;
22696 cursor_x=msg_margins[left];
22697 return true;
22698 }
22699
22700 case MSGC_COLOUR:
22701 {
22702 int32_t cset = (grab_next_argument());
22703 msgcolour = CSET(cset)+(grab_next_argument());
22704 return true;
22705 }
22706
22707 case MSGC_SHDCOLOR:
22708 {
22709 int32_t cset = (grab_next_argument());
22710 msg_shdcol = CSET(cset)+(grab_next_argument());
22711 return true;
22712 }
22713 case MSGC_SHDTYPE:
22714 {
22715 msg_shdtype = grab_next_argument();
22716 return true;
22717 }
22718
22719 case MSGC_SPEED:
22720 {
22721 msgspeed=grab_next_argument();
22722 return true;
22723 }
22724
22725 case MSGC_CTRUP:
22726 {
22727 int32_t a1 = grab_next_argument();
22728 int32_t a2 = grab_next_argument();
22729 game->change_counter(a2, a1);
22730 return true;
22731 }
22732
22733 case MSGC_CTRDN:
22734 {
22735 int32_t a1 = grab_next_argument();
22736 int32_t a2 = grab_next_argument();
22737 game->change_counter(-a2, a1);
22738 return true;
22739 }
22740
22741 case MSGC_CTRSET:
22742 {
22743 int32_t a1 = grab_next_argument();
22744 int32_t a2 = grab_next_argument();
22745 game->set_counter(vbound(a2, 0, game->get_maxcounter(a1)), a1);
22746 return true;
22747 }
22748
22749 case MSGC_CTRUPPC:
22750 case MSGC_CTRDNPC:
22751 case MSGC_CTRSETPC:
22752 {
22753 int32_t code = MsgStrings[msgstr].s[msgptr]-1;
22754 int32_t counter = grab_next_argument();
22755 int32_t amount = grab_next_argument();
22756 amount = int32_t(vbound(amount*0.01, 0.0, 1.0)*game->get_maxcounter(counter));
22757
22758 if(code==MSGC_CTRDNPC)
22759 amount*=-1;
22760
22761 if(code==MSGC_CTRSETPC)
22762 game->set_counter(amount, counter);
22763 else
22764 game->change_counter(amount, counter);
22765
22766 return true;
22767 }
22768
22769 case MSGC_GIVEITEM:
22770 {
22771 int32_t itemID = grab_next_argument();
22772
22773 getitem(itemID, true);
22774 if ( !item_doscript[itemID] && (((unsigned)itemID) < 256) )
22775 {
22776 itemScriptData[itemID].Clear();
22777 memset(item_stack[itemID], 0xFFFF, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
22778 if ( (itemsbuf[itemID].flags&ITEM_PASSIVESCRIPT) ) item_doscript[itemID] = 1;
22779 }
22780 return true;
22781 }
22782
22783
22784 case MSGC_WARP:
22785 {
22786 int32_t dmap = grab_next_argument();
22787 int32_t scrn = grab_next_argument();
22788 int32_t dx = grab_next_argument();
22789 int32_t dy = grab_next_argument();
22790 int32_t wfx = grab_next_argument();
22791 int32_t sfx = grab_next_argument();
22792 if(dx >= MAX_SCC_ARG) dx = -1;
22793 if(dy >= MAX_SCC_ARG) dy = -1;
22794 FFCore.warp_player(wtIWARP, dmap, scrn, dx, dy, wfx, sfx, warpFlagDONTKILLMUSIC, 0);
22795 return true;
22796 }
22797
22798 case MSGC_SETSCREEND:
22799 {
22800 int32_t dmap = (grab_next_argument()<<7); //dmap and screen may be transposed here.
22801 int32_t screen = grab_next_argument();
22802 int32_t reg = grab_next_argument();
22803 int32_t val = grab_next_argument();
22804 FFCore.set_screen_d(screen + dmap, reg, val);
22805 return true;
22806 }
22807 case MSGC_TAKEITEM:
22808 {
22809 int32_t itemID = grab_next_argument();
22810 if ( item_doscript[itemID] )
22811 {
22812 item_doscript[itemID] = 4; //Val of 4 means 'clear stack and quit'
22813 }
22814 takeitem(itemID);
22815 if ( game->forced_bwpn == itemID )
22816 {
22817 game->forced_bwpn = -1;
22818 } //not else if! -Z
22819 if ( game->forced_awpn == itemID )
22820 {
22821 game->forced_awpn = -1;
22822 }
22823 if ( game->forced_xwpn == itemID )
22824 {
22825 game->forced_xwpn = -1;
22826 } //not else if! -Z
22827 if ( game->forced_ywpn == itemID )
22828 {
22829 game->forced_ywpn = -1;
22830 }
22831 verifyBothWeapons();
22832 return true;
22833 }
22834
22835 case MSGC_SFX:
22836 {
22837 sfx((int32_t)grab_next_argument(),128);
22838 return true;
22839 }
22840
22841 case MSGC_MIDI:
22842 {
22843 int32_t music = (int32_t)(grab_next_argument());
22844
22845 if(music==0)
22846 music_stop();
22847 else
22848 jukebox(music+(ZC_MIDI_COUNT-1));
22849
22850 return true;
22851 }
22852
22853 case MSGC_NAME:
22854 {
22855 doing_name_insert = true;
22856 sprintf(namebuf, "%s", game->get_name());
22857 nameptr = namebuf;
22858 return true;
22859 }
22860
22861 case MSGC_DRAWTILE:
22862 {
22863 int32_t tl = grab_next_argument();
22864 int32_t cs = grab_next_argument();
22865 int32_t t_wid = grab_next_argument();
22866 int32_t t_hei = grab_next_argument();
22867 int32_t fl = grab_next_argument();
22868
22869 if(cursor_x+MsgStrings[msgstr].hspace + t_wid > msg_w-msg_margins[right])
22870 {
22871 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
22872 ssc_tile_hei = ssc_tile_hei_buf;
22873 ssc_tile_hei_buf = -1;
22874 cursor_y += thei + MsgStrings[msgstr].vspace;
22875 if(bottom_margin_clip()) return true;
22876 cursor_x=msg_margins[left];
22877 }
22878
22879 overtileblock16(msg_txt_bmp_buf, tl, cursor_x, cursor_y, (int32_t)ceil(t_wid/16.0), (int32_t)ceil(t_hei/16.0), cs, fl);
22880 ssc_tile_hei_buf = zc_max(ssc_tile_hei_buf, t_hei);
22881 cursor_x += MsgStrings[msgstr].hspace + t_wid;
22882 return true;
22883 }
22884
22885 case MSGC_GOTOIFRAND:
22886 {
22887 int32_t odds = (int32_t)(grab_next_argument());
22888
22889 if(!odds || !(zc_oldrand()%odds))
22890 goto switched;
22891
22892 (void)grab_next_argument();
22893 return true;
22894 }
22895
22896 case MSGC_GOTOIFGLOBAL:
22897 {
22898 int32_t arg = (int32_t)grab_next_argument();
22899 int32_t d = zc_min(7,arg);
22900 int32_t s = ((get_currdmap())<<7) + get_currscr()-(DMaps[get_currdmap()].type==dmOVERW ? 0 : DMaps[get_currdmap()].xoff);
22901 arg = (int32_t)grab_next_argument();
22902
22903 if(game->screen_d[s][d] >= arg)
22904 goto switched;
22905
22906 (void)grab_next_argument();
22907 return true;
22908 }
22909
22910 case MSGC_CHANGEPORTRAIT:
22911 {
22912 return true; //not implemented
22913 }
22914
22915 case MSGC_GOTOIFCREEND:
22916 {
22917 int32_t dmap = (grab_next_argument()<<7); //dmap and screen may be transposed here.
22918 int32_t screen = grab_next_argument();
22919 int32_t reg = grab_next_argument();
22920 int32_t val = grab_next_argument();
22921 //int32_t nxtstr = grab_next_argument();
22922 if ( FFCore.get_screen_d(screen + dmap, reg) >= val )
22923 {
22924 goto switched;
22925 }
22926 (void)grab_next_argument();
22927 return true;
22928 }
22929
22930 case MSGC_GOTOIF:
22931 {
22932 int32_t it = (int32_t)grab_next_argument();
22933
22934 if(unsigned(it)<MAXITEMS && game->item[it])
22935 goto switched;
22936
22937 (void)grab_next_argument();
22938 return true;
22939 }
22940
22941 case MSGC_GOTOIFCTR:
22942 {
22943 if(game->get_counter(grab_next_argument())>=grab_next_argument())
22944 goto switched;
22945
22946 (void)grab_next_argument();
22947 return true;
22948 }
22949
22950 case MSGC_GOTOIFCTRPC:
22951 {
22952 int32_t counter = grab_next_argument();
22953 int32_t amount = (int32_t)(((grab_next_argument())/100)*game->get_maxcounter(counter));
22954
22955 if(game->get_counter(counter)>=amount)
22956 goto switched;
22957
22958 (void)grab_next_argument();
22959 return true;
22960 }
22961
22962 case MSGC_GOTOIFTRICOUNT:
22963 {
22964 if(TriforceCount() >= (int32_t)(grab_next_argument()))
22965 goto switched;
22966
22967 (void)grab_next_argument();
22968 return true;
22969 }
22970
22971 case MSGC_GOTOIFTRI:
22972 {
22973 int32_t lev = (int32_t)(grab_next_argument());
22974
22975 if(lev<MAXLEVELS && game->lvlitems[lev]&liTRIFORCE)
22976 goto switched;
22977
22978 (void)grab_next_argument();
22979 return true;
22980 }
22981
22982 case MSGC_SETUPMENU:
22983 {
22984 msg_menu_data[MNU_CURSOR_TILE] = grab_next_argument();
22985 msg_menu_data[MNU_CURSOR_CSET] = grab_next_argument();
22986 msg_menu_data[MNU_CURSOR_WID] = grab_next_argument();
22987 msg_menu_data[MNU_CURSOR_HEI] = grab_next_argument();
22988 msg_menu_data[MNU_CURSOR_FLIP] = grab_next_argument();
22989 return true;
22990 }
22991
22992 case MSGC_MENUCHOICE:
22993 {
22994 int32_t pos = grab_next_argument();
22995 int32_t upos = grab_next_argument();
22996 int32_t dpos = grab_next_argument();
22997 int32_t lpos = grab_next_argument();
22998 int32_t rpos = grab_next_argument();
22999 if(cursor_x+MsgStrings[msgstr].hspace + msg_menu_data[MNU_CURSOR_WID] > msg_w-msg_margins[right])
23000 {
23001 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23002 ssc_tile_hei = ssc_tile_hei_buf;
23003 ssc_tile_hei_buf = -1;
23004 cursor_y += thei + MsgStrings[msgstr].vspace;
23005 if(bottom_margin_clip()) break;
23006 cursor_x=msg_margins[left];
23007 }
23008
23009 menu_options[pos] = menu_choice(cursor_x, cursor_y, pos,
23010 upos, dpos, lpos, rpos);
23011
23012 ssc_tile_hei_buf = zc_max(ssc_tile_hei_buf, msg_menu_data[MNU_CURSOR_HEI]);
23013 cursor_x += MsgStrings[msgstr].hspace + msg_menu_data[MNU_CURSOR_WID];
23014 return true;
23015 }
23016
23017 case MSGC_RUNMENU:
23018 {
23019 msg_menu_data[MNU_CHOSEN] = 0;
23020 msg_menu_data[MNU_CAN_CONFIRM] = 0;
23021 if(menu_options.size() < 1)
23022 return true;
23023 do_run_menu = true;
23024 return true;
23025 }
23026
23027 case MSGC_GOTOMENUCHOICE:
23028 {
23029 int32_t choice = grab_next_argument();
23030 if(msg_menu_data[MNU_CHOSEN] == choice)
23031 goto switched;
23032 (void)grab_next_argument();
23033 return true;
23034 }
23035
23036 case MSGC_ENDSTRING:
23037 {
23038 do_end_str = true;
23039 return true;
23040 }
23041 case MSGC_WAIT_ADVANCE:
23042 {
23043 wait_advance = true;
23044 linkedmsgclk = 51;
23045 return true;
23046 }
23047 case MSGC_TRIGSECRETS:
23048 {
23049 bool perm = (bool)grab_next_argument();
23050 hidden_entrance(0, true, false, -8);
23051 if(perm)
23052 setmapflag(mSECRET);
23053 return true;
23054 }
23055 case MSGC_SETSCREENSTATE:
23056 {
23057 int32_t flag = int32_t(grab_next_argument());
23058 if(unsigned(flag)>=mMAXIND)
23059 {
23060 Z_error("SCC 133: Flag %d is invalid\n", flag);
23061 return true;
23062 }
23063 bool state = bool(grab_next_argument());
23064 if(state)
23065 setmapflag(1<<flag);
23066 else
23067 unsetmapflag(1<<flag,true);
23068 return true;
23069 }
23070 case MSGC_SETSCREENSTATER:
23071 {
23072 int32_t map = (int32_t)grab_next_argument();
23073 int32_t scrid = (int32_t)grab_next_argument();
23074 if(map < 1 || map > map_count)
23075 {
23076 Z_error("SCC 134: Map %d is invalid\n", map);
23077 return true;
23078 }
23079 if(unsigned(scrid)>=0x80)
23080 {
23081 Z_error("SCC 134: Screen %d is invalid\n", scrid);
23082 return true;
23083 }
23084
23085 int32_t flag = int32_t(grab_next_argument());
23086 if(unsigned(flag)>=mMAXIND)
23087 {
23088 Z_error("SCC 134: Flag %d is invalid\n", flag);
23089 return true;
23090 }
23091 bool state = bool(grab_next_argument());
23092 if(state)
23093 setmapflag(mapind(map,scrid),1<<flag);
23094 else
23095 unsetmapflag(mapind(map,scrid),1<<flag,true);
23096 return true;
23097 }
23098 switched:
23099 int32_t lev = (int32_t)(grab_next_argument());
23100 if(lev && get_bit(quest_rules, qr_SCC_GOTO_RESPECTS_CONTFLAG)
23101 && (MsgStrings[lev].stringflags & STRINGFLAG_CONT))
23102 {
23103 msgstr=lev;
23104 msgpos=msgptr=0;
23105 msgfont=setmsgfont();
23106 }
23107 else donewmsg(lev);
23108 msgptr--; // To counteract it being incremented after this routine is called.
23109 putprices(false);
23110 return true;
23111 }
23112
23113 144 return false;
23114 148 }
23115
23116 // Wraps the message string... probably.
23117 144 void wrapmsgstr(char *s3)
23118 {
23119 144 int32_t j=0;
23120
23121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
144 if(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP)
23122 {
23123 if(msgspace)
23124 {
23125 char c = MsgStrings[msgstr].s[msgptr];
23126 if(c != ' ' && c >= 32 && c <= 126)
23127 {
23128 for(int32_t k=0; MsgStrings[msgstr].s[msgptr+k] && MsgStrings[msgstr].s[msgptr+k] != ' '; k++)
23129 {
23130 if(MsgStrings[msgstr].s[msgptr+k] >= 32 && MsgStrings[msgstr].s[msgptr+k] <= 126) s3[j++] = MsgStrings[msgstr].s[msgptr+k];
23131 }
23132
23133 s3[j] = 0;
23134 msgspace = false;
23135 }
23136 else
23137 {
23138 s3[0] = c;
23139 s3[1] = 0;
23140 }
23141 }
23142 else
23143 {
23144 s3[0] = MsgStrings[msgstr].s[msgptr];
23145 s3[1] = 0;
23146
23147 if(s3[0] == ' ') msgspace=true;
23148 }
23149 }
23150 else
23151 {
23152 144 s3[0] = MsgStrings[msgstr].s[msgptr];
23153 144 s3[1] = 0;
23154 }
23155 144 }
23156
23157 // Returns true if the pointer is at a string's
23158 // null terminator or a trailing space
23159 572 bool atend(char const* str)
23160 {
23161 572 int32_t i=0;
23162
23163
2/2
✓ Branch 0 taken 1726 times.
✓ Branch 1 taken 572 times.
2298 while(str[i]==' ')
23164 1726 i++;
23165
23166 572 return str[i]=='\0';
23167 }
23168
23169 23254 void putmsg()
23170 {
23171 23254 bool oldmargin = get_bit(quest_rules, qr_OLD_STRING_EDITOR_MARGINS)!=0;
23172
2/2
✓ Branch 0 taken 22137 times.
✓ Branch 1 taken 1117 times.
23254 if(!msgorig) msgorig=msgstr;
23173
23174
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 23254 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
23254 if(wait_advance && linkedmsgclk < 1)
23175 linkedmsgclk = 1;
23176
1/2
✓ Branch 0 taken 23254 times.
✗ Branch 1 not taken.
23254 if(linkedmsgclk>0)
23177 {
23178 if(linkedmsgclk==1)
23179 {
23180 if(do_end_str||cAbtn()||cBbtn())
23181 {
23182 do_end_str = false;
23183 linkedmsgclk = 0;
23184 if(wait_advance)
23185 {
23186 wait_advance = false;
23187 }
23188 else
23189 {
23190 msgstr=MsgStrings[msgstr].nextstring;
23191 if(!msgstr && enqueued_str)
23192 {
23193 msgstr = enqueued_str;
23194 enqueued_str = 0;
23195 }
23196 if(!msgstr)
23197 {
23198 msgfont=zfont;
23199
23200 if(tmpscr->room!=rGRUMBLE)
23201 blockpath=false;
23202
23203 dismissmsg();
23204 goto disappear;
23205 }
23206
23207 donewmsg(msgstr);
23208 putprices(false);
23209 }
23210 }
23211 }
23212 else
23213 {
23214 --linkedmsgclk;
23215 }
23216 }
23217
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23254 times.
23254 if(wait_advance) return; //Waiting for buttonpress
23218
23219
7/10
✓ Branch 0 taken 23254 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1113 times.
✓ Branch 3 taken 22141 times.
✓ Branch 4 taken 1113 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 864 times.
✓ Branch 7 taken 249 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 864 times.
23254 if(!do_run_menu && (!msgstr || msgpos>=10000 || msgptr>=MsgStrings[msgstr].s.size() || bottom_margin_clip()))
23220 {
23221
2/2
✓ Branch 0 taken 249 times.
✓ Branch 1 taken 22141 times.
22390 if(!msgstr)
23222 22141 msgorig=0;
23223
23224 22390 msg_active = false;
23225 22390 return;
23226 }
23227
23228 864 msg_onscreen = true; // Now the message is onscreen (see donewmsg()).
23229
23230 char s3[145];
23231 int32_t tlength;
23232
23233 // Bypass the string with the B button!
23234
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 864 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 864 times.
864 if(((cBbtn())&&(get_bit(quest_rules,qr_ALLOWMSGBYPASS))) || msgspeed==0)
23235 {
23236 //finish writing out the string
23237 while(msgptr<MsgStrings[msgstr].s.size() && !atend(MsgStrings[msgstr].s.c_str()+msgptr))
23238 {
23239 if(msgspeed && !(cBbtn() && get_bit(quest_rules,qr_ALLOWMSGBYPASS)))
23240 goto breakout; // break out if message speed was changed to non-zero
23241 else if(!do_run_menu && !doing_name_insert && !parsemsgcode())
23242 {
23243 if(bottom_margin_clip())
23244 break;
23245
23246 wrapmsgstr(s3);
23247
23248 if(MsgStrings[msgstr].s[msgptr]==' ')
23249 {
23250 tlength = msgfont->vtable->char_length(msgfont, MsgStrings[msgstr].s[msgptr]) + MsgStrings[msgstr].hspace;
23251
23252 if(cursor_x+tlength > (msg_w-msg_margins[right])
23253 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23254 ? true : strcmp(s3," ")!=0))
23255 {
23256 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23257 ssc_tile_hei = ssc_tile_hei_buf;
23258 ssc_tile_hei_buf = -1;
23259 cursor_y += thei + MsgStrings[msgstr].vspace;
23260 if(bottom_margin_clip()) break;
23261 cursor_x=msg_margins[left];
23262 }
23263
23264 char buf[2] = {0};
23265 sprintf(buf,"%c",MsgStrings[msgstr].s[msgptr]);
23266
23267 textout_styled_aligned_ex(msg_txt_bmp_buf,msgfont,buf,cursor_x,cursor_y,msg_shdtype,sstaLEFT,msgcolour,msg_shdcol,-1);
23268
23269 cursor_x+=tlength;
23270 }
23271 else
23272 {
23273 tlength = text_length(msgfont, s3) + ((int32_t)strlen(s3)*MsgStrings[msgstr].hspace);
23274 if(cursor_x+tlength > (msg_w-msg_margins[right])
23275 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23276 ? true : strcmp(s3," ")!=0))
23277 {
23278 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23279 ssc_tile_hei = ssc_tile_hei_buf;
23280 ssc_tile_hei_buf = -1;
23281 cursor_y += thei + MsgStrings[msgstr].vspace;
23282 if(bottom_margin_clip()) break;
23283 cursor_x=msg_margins[left];
23284 }
23285
23286 sfx(MsgStrings[msgstr].sfx);
23287
23288 char buf[2] = {0};
23289 sprintf(buf,"%c",MsgStrings[msgstr].s[msgptr]);
23290
23291 textout_styled_aligned_ex(msg_txt_bmp_buf,msgfont,buf,cursor_x,cursor_y,msg_shdtype,sstaLEFT,msgcolour,msg_shdcol,-1);
23292
23293 cursor_x += msgfont->vtable->char_length(msgfont, MsgStrings[msgstr].s[msgptr]);
23294 cursor_x += MsgStrings[msgstr].hspace;
23295 }
23296
23297 msgpos++;
23298 }
23299 if(do_run_menu)
23300 {
23301 if(runMenuCursor())
23302 {
23303 do_run_menu = false;
23304 }
23305 else break;
23306 }
23307 if(doing_name_insert)
23308 {
23309 if(*nameptr)
23310 {
23311 if(bottom_margin_clip())
23312 break;
23313
23314 char s3[9] = {0};
23315
23316 if(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP)
23317 {
23318 strcpy(s3, nameptr);
23319 }
23320 else
23321 {
23322 s3[0] = *nameptr;
23323 s3[1] = 0;
23324 }
23325
23326 tlength = text_length(msgfont, s3) + ((int32_t)strlen(s3)*MsgStrings[msgstr].hspace);
23327
23328 if(cursor_x+tlength > (msg_w-msg_margins[right])
23329 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23330 ? true : strcmp(s3," ")!=0))
23331 {
23332 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23333 ssc_tile_hei = ssc_tile_hei_buf;
23334 ssc_tile_hei_buf = -1;
23335 cursor_y += thei + MsgStrings[msgstr].vspace;
23336 if(bottom_margin_clip()) break;
23337 cursor_x=msg_margins[left];
23338 }
23339
23340 sfx(MsgStrings[msgstr].sfx);
23341
23342 char buf[2] = {0};
23343 sprintf(buf,"%c",*nameptr);
23344
23345 textout_styled_aligned_ex(msg_txt_bmp_buf,msgfont,buf,cursor_x,cursor_y,msg_shdtype,sstaLEFT,msgcolour,msg_shdcol,-1);
23346
23347 cursor_x += msgfont->vtable->char_length(msgfont, *nameptr);
23348 cursor_x += MsgStrings[msgstr].hspace;
23349 ++nameptr;
23350 continue; //don't advance the msgptr, as the next char in it was not processed!
23351 }
23352 else doing_name_insert = false;
23353 }
23354 ++msgptr;
23355 if(do_end_str)
23356 goto strendcheck;
23357 if(wait_advance)
23358 return;
23359 if(atend(MsgStrings[msgstr].s.c_str()+msgptr))
23360 {
23361 if(MsgStrings[msgstr].nextstring)
23362 {
23363 if(MsgStrings[MsgStrings[msgstr].nextstring].stringflags & STRINGFLAG_CONT)
23364 {
23365 msgstr=MsgStrings[msgstr].nextstring;
23366 msgpos=msgptr=0;
23367 msgfont=setmsgfont();
23368 }
23369 }
23370 }
23371 }
23372
23373 if (!do_run_menu)
23374 {
23375 msgclk = 72;
23376 msgpos = 10000;
23377 }
23378 }
23379 else
23380 864 {
23381 breakout:
23382
23383
5/6
✓ Branch 0 taken 720 times.
✓ Branch 1 taken 144 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 715 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 5 times.
864 if(((msgclk++)%(msgspeed+1)<msgspeed)&&((!cAbtn())||(!get_bit(quest_rules,qr_ALLOWFASTMSG))))
23384 720 return;
23385 }
23386
23387 // Start writing the string
23388
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 4 times.
148 if(msgptr == 0)
23389 {
23390
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
12 while(MsgStrings[msgstr].s[msgptr]==' ')
23391 {
23392 8 tlength = msgfont->vtable->char_length(msgfont, MsgStrings[msgstr].s[msgptr]) + MsgStrings[msgstr].hspace;
23393
23394
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
8 if(cursor_x+tlength > (msg_w-msg_margins[right])
23395
1/6
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
8 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23396 ? 1 : strcmp(s3," ")!=0))
23397 {
23398 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23399 ssc_tile_hei = ssc_tile_hei_buf;
23400 ssc_tile_hei_buf = -1;
23401 cursor_y += thei + MsgStrings[msgstr].vspace;
23402 if(bottom_margin_clip()) break;
23403 cursor_x=msg_margins[left];
23404 }
23405
23406 8 cursor_x+=tlength;
23407 8 ++msgptr;
23408 8 ++msgpos;
23409
23410 // The "Continue From Previous" feature
23411
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if(atend(MsgStrings[msgstr].s.c_str()+msgptr))
23412 {
23413 if(MsgStrings[msgstr].nextstring)
23414 {
23415 if(MsgStrings[MsgStrings[msgstr].nextstring].stringflags & STRINGFLAG_CONT)
23416 {
23417 msgstr=MsgStrings[msgstr].nextstring;
23418 msgpos=msgptr=0;
23419 msgfont=setmsgfont();
23420 }
23421 }
23422 }
23423 }
23424 4 }
23425
23426 reparsesinglechar:
23427 // Continue printing the string!
23428
2/4
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 144 times.
288 if(!atend(MsgStrings[msgstr].s.c_str()+msgptr) && !bottom_margin_clip())
23429 {
23430
3/6
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 144 times.
144 if(!do_run_menu && !doing_name_insert && !parsemsgcode())
23431 {
23432 144 wrapmsgstr(s3);
23433
23434 144 tlength = text_length(msgfont, s3) + ((int32_t)strlen(s3)*MsgStrings[msgstr].hspace);
23435
23436
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
144 if(cursor_x+tlength > (msg_w-msg_margins[right])
23437
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
144 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23438 ? true : strcmp(s3," ")!=0))
23439 {
23440 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23441 ssc_tile_hei = ssc_tile_hei_buf;
23442 ssc_tile_hei_buf = -1;
23443 cursor_y += thei + MsgStrings[msgstr].vspace;
23444 if(bottom_margin_clip()) goto strendcheck;
23445 cursor_x=msg_margins[left];
23446 //if(space) s3[0]=0;
23447 }
23448
23449 144 sfx(MsgStrings[msgstr].sfx);
23450
23451 144 char buf[2] = {0};
23452 144 sprintf(buf,"%c",MsgStrings[msgstr].s[msgptr]);
23453
23454 144 textout_styled_aligned_ex(msg_txt_bmp_buf,msgfont,buf,cursor_x,cursor_y,msg_shdtype,sstaLEFT,msgcolour,msg_shdcol,-1);
23455
23456 144 cursor_x += msgfont->vtable->char_length(msgfont, MsgStrings[msgstr].s[msgptr]);
23457 144 cursor_x += MsgStrings[msgstr].hspace;
23458 144 msgpos++;
23459 144 }
23460
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 if(do_end_str)
23461 goto strendcheck;
23462
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 if(wait_advance)
23463 {
23464 ++msgptr;
23465 return;
23466 }
23467
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
144 else if(do_run_menu)
23468 {
23469 if(runMenuCursor())
23470 {
23471 do_run_menu = false;
23472 ++msgptr;
23473 goto reparsesinglechar;
23474 }
23475 }
23476
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
144 else if(doing_name_insert && *nameptr)
23477 {
23478 char s3[9] = {0};
23479
23480 if(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP)
23481 {
23482 strcpy(s3, nameptr);
23483 }
23484 else
23485 {
23486 s3[0] = *nameptr;
23487 s3[1] = 0;
23488 }
23489
23490 tlength = text_length(msgfont, s3) + ((int32_t)strlen(s3)*MsgStrings[msgstr].hspace);
23491
23492 if(cursor_x+tlength > (msg_w-msg_margins[right])
23493 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23494 ? true : strcmp(s3," ")!=0))
23495 {
23496 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23497 ssc_tile_hei = ssc_tile_hei_buf;
23498 ssc_tile_hei_buf = -1;
23499 cursor_y += thei + MsgStrings[msgstr].vspace;
23500 if(bottom_margin_clip()) goto strendcheck;
23501 cursor_x=msg_margins[left];
23502 }
23503
23504 sfx(MsgStrings[msgstr].sfx);
23505
23506 char buf[2] = {0};
23507 sprintf(buf,"%c",*nameptr);
23508
23509 textout_styled_aligned_ex(msg_txt_bmp_buf,msgfont,buf,cursor_x,cursor_y,msg_shdtype,sstaLEFT,msgcolour,msg_shdcol,-1);
23510
23511 cursor_x += msgfont->vtable->char_length(msgfont, *nameptr);
23512 cursor_x += MsgStrings[msgstr].hspace;
23513 ++nameptr;
23514 }
23515 else
23516 {
23517 144 doing_name_insert = false;
23518 144 msgptr++;
23519
23520
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 4 times.
144 if(atend(MsgStrings[msgstr].s.c_str()+msgptr))
23521 {
23522
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(MsgStrings[msgstr].nextstring)
23523 {
23524 if(MsgStrings[MsgStrings[msgstr].nextstring].stringflags & STRINGFLAG_CONT)
23525 {
23526 msgstr=MsgStrings[msgstr].nextstring;
23527 msgpos=msgptr=0;
23528 msgfont=setmsgfont();
23529 }
23530 }
23531 4 }
23532
23533
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 8 times.
170 if(MsgStrings[msgstr].s.size() > unsigned(msgptr+1)
23534
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 && (MsgStrings[msgstr].s[msgptr]==' ')
23535
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 118 times.
144 && (MsgStrings[msgstr].s[msgptr+1]==' '))
23536 {
23537
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 136 times.
144 while(MsgStrings[msgstr].s[msgptr]==' ')
23538 {
23539 136 msgspace = true;
23540 136 tlength = msgfont->vtable->char_length(msgfont, MsgStrings[msgstr].s[msgptr]) + MsgStrings[msgstr].hspace;
23541
23542
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
144 if(cursor_x+tlength > (msg_w-msg_margins[right])
23543
4/6
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 128 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
136 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23544 ? true : strcmp(s3," ")!=0))
23545 {
23546
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23547 8 ssc_tile_hei = ssc_tile_hei_buf;
23548 8 ssc_tile_hei_buf = -1;
23549 8 cursor_y += thei + MsgStrings[msgstr].vspace;
23550
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if(bottom_margin_clip()) break;
23551 8 cursor_x=msg_margins[left];
23552 8 }
23553
23554 136 cursor_x+=tlength;
23555 136 ++msgpos;
23556 136 ++msgptr;
23557
23558
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 110 times.
136 if(atend(MsgStrings[msgstr].s.c_str()+msgptr))
23559 {
23560
1/2
✓ Branch 0 taken 110 times.
✗ Branch 1 not taken.
110 if(MsgStrings[msgstr].nextstring)
23561 {
23562 if(MsgStrings[MsgStrings[msgstr].nextstring].stringflags & STRINGFLAG_CONT)
23563 {
23564 msgstr=MsgStrings[msgstr].nextstring;
23565 msgpos=msgptr=0;
23566 msgfont=setmsgfont();
23567 }
23568 }
23569 110 }
23570 }
23571 8 }
23572 }
23573 144 }
23574 strendcheck:
23575 // Done printing the string
23576
9/14
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 144 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 144 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 140 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 140 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 140 times.
✓ Branch 13 taken 4 times.
144 if(do_end_str || !doing_name_insert && !do_run_menu && (msgpos>=10000 || msgptr>=MsgStrings[msgstr].s.size() || bottom_margin_clip() || atend(MsgStrings[msgstr].s.c_str()+msgptr)) && !linkedmsgclk)
23577 {
23578
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!do_end_str)
23579
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 while(parsemsgcode()); // Finish remaining control codes
23580
23581 // Go to next string, or make it disappear by going to string 0.
23582
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(MsgStrings[msgstr].nextstring!=0 || get_bit(quest_rules,qr_MSGDISAPPEAR) || enqueued_str)
23583 {
23584 linkedmsgclk=do_end_str?1:51;
23585 }
23586
23587
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(MsgStrings[msgstr].nextstring==0)
23588 {
23589
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!get_bit(quest_rules,qr_MSGDISAPPEAR))
23590 4 {
23591 disappear:
23592 4 msg_active = false;
23593 4 Hero.finishedmsg();
23594 4 }
23595
23596
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(repaircharge)
23597 {
23598 // if (get_bit(quest_rules,qr_REPAIRFIX)) {
23599 // fixed_door=true;
23600 // }
23601 game->change_drupy(-tmpscr[currscr<128?0:1].catchall);
23602 repaircharge = 0;
23603 }
23604
23605
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(adjustmagic)
23606 {
23607 if(get_bit(quest_rules,qr_OLD_HALF_MAGIC))
23608 {
23609 if(game->get_magicdrainrate())
23610 game->set_magicdrainrate(1);
23611 }
23612 else if(game->get_magicdrainrate() > 1)
23613 {
23614 game->set_magicdrainrate(game->get_magicdrainrate()/2);
23615 }
23616 adjustmagic = false;
23617 sfx(WAV_SCALE);
23618 setmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM);
23619 }
23620
23621
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(learnslash)
23622 {
23623 game->set_canslash(1);
23624 learnslash = false;
23625 sfx(WAV_SCALE);
23626 setmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM);
23627 }
23628 4 }
23629 4 }
23630 23254 }
23631
23632 int32_t message_more_y()
23633 {
23634 //Is the flag ticked, do we really want a message more y larger than 160?
23635 int32_t msgy=zc_min((zinit.msg_more_is_offset==0)?zinit.msg_more_y:zinit.msg_more_y+MsgStrings[msgstr].y ,160);
23636 msgy+=playing_field_offset;
23637 return msgy;
23638 }
23639
23640 /*** Collision detection & handling ***/
23641
23642 23254 void clear_script_one_frame_conditions()
23643 {
23644
2/2
✓ Branch 0 taken 52875 times.
✓ Branch 1 taken 23254 times.
76129 for(int32_t j=0; j<guys.Count(); j++)
23645 {
23646 52875 enemy *e = (enemy*)guys.spr(j);
23647
2/2
✓ Branch 0 taken 846000 times.
✓ Branch 1 taken 52875 times.
898875 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) e->hitby[q] = 0;
23648 52875 }
23649 23254 }
23650
23651 23254 void check_collisions()
23652 {
23653 23254 bool temp_hit = false;
23654
2/2
✓ Branch 0 taken 4089 times.
✓ Branch 1 taken 23254 times.
27343 for(int32_t i=0; i<Lwpns.Count(); i++)
23655 {
23656 4089 weapon *w = (weapon*)Lwpns.spr(i);
23657
23658
6/8
✓ Branch 0 taken 2664 times.
✓ Branch 1 taken 1425 times.
✓ Branch 2 taken 1431 times.
✓ Branch 3 taken 1233 times.
✓ Branch 4 taken 1431 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1431 times.
4089 if(!(w->Dead()) && w->id!=wSword && w->id!=wHammer && w->id!=wWand)
23659 {
23660
2/2
✓ Branch 0 taken 1387 times.
✓ Branch 1 taken 3311 times.
4698 for(int32_t j=0; j<guys.Count(); j++)
23661 {
23662 3311 enemy *e = (enemy*)guys.spr(j);
23663
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3311 times.
3311 if ( !temp_hit ) e->hitby[HIT_BY_LWEAPON] = 0;
23664
23665
2/2
✓ Branch 0 taken 3267 times.
✓ Branch 1 taken 44 times.
3311 if(e->hit(w)) //boomerangs and such that last for more than a frame can write hitby[] for more than one frame,
23666 //because this only checks `if(dying || clk<0 || hclk>0 || superman)`
23667 {
23668 // !(e->stunclk)
23669 44 int32_t h = e->takehit(w);
23670
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44 times.
44 if (h == -1)
23671 {
23672 44 e->hitby[HIT_BY_LWEAPON] = i+1; temp_hit = true;
23673 44 e->hitby[HIT_BY_LWEAPON_UID] = w->script_UID;
23674 //e->hitby[HIT_BY_LWEAPON_FAMILY] = itemsbuf[w->parentid].family; //that would be the itemclass, not the weapon type!
23675 44 e->hitby[HIT_BY_LWEAPON_FAMILY] = w->id;
23676 //al_trace("npc->HitBy[] Parent Item is: %d /n", w->parentitem);
23677 //al_trace("npc->HitBy[] Parent ID is: %d /n", w->parentid);
23678 44 e->hitby[HIT_BY_LWEAPON_LITERAL_ID] = w->parentitem;
23679
23680 44 }
23681 //we may need to handle this in special cases. -Z
23682
23683 //if h == stun or ignore
23684
23685 //if e->stun > DEFAULT_STUN -1 || !e->stun
23686 //if the enemy wasn't stunned this round -- what a bitch, as the stun value is set before we check this
23687 ///! how about: if w->dead != bounce !
23688
23689 // NOT FOR PUBLIC RELEASE
23690 /*if(h==3) //Mirror shield
23691 {
23692 if (w->id==ewFireball || w->id==wRefFireball)
23693 {
23694 w->id=wRefFireball;
23695 switch(e->dir)
23696 {
23697 case up: e->angle += (PI - e->angle) * 2.0; break;
23698 case down: e->angle = -e->angle; break;
23699 case left: e->angle += ((-PI/2) - e->angle) * 2.0; break;
23700 case right: e->angle += (( PI/2) - e->angle) * 2.0; break;
23701 // TODO: the following. -L.
23702 case l_up: break;
23703 case r_up: break;
23704 case l_down: break;
23705 case r_down: break;
23706 }
23707 }
23708 else
23709 {
23710 w->id = ((w->id==ewMagic || w->id==wRefMagic || w->id==wMagic) ? wRefMagic : wRefBeam);
23711 w->dir ^= 1;
23712 if(w->dir&2)
23713 w->flip ^= 1;
23714 else
23715 w->flip ^= 2;
23716 }
23717 w->ignoreHero=false;
23718 }
23719 else*/
23720
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44 times.
44 if(h)
23721 {
23722
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
44 if(e->switch_hooked && w->family_class == itype_switchhook)
23723 w->onhit(false, e, -1);
23724 44 else w->onhit(false, e, h);
23725 44 }
23726
23727
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 if(h==2)
23728 {
23729 break;
23730 }
23731 44 }
23732
23733
2/2
✓ Branch 0 taken 3267 times.
✓ Branch 1 taken 44 times.
3311 if(w->Dead())
23734 {
23735 44 break;
23736 }
23737 3267 }
23738
23739 // Item flags added in 2.55:
23740 // BRang/HShot/Arrows ITEM_FLAG4 is "Pick up anything" (port of qr_BRANGPICKUP)
23741 // BRang/HShot ITEM_FLAG5 is "Drags Items" (port of qr_Z3BRANG_HSHOT)
23742 // Arrows ITEM_FLAG2 is "Picks up items" (inverse port of qr_Z3BRANG_HSHOT)
23743 // -V
23744
3/6
✓ Branch 0 taken 1431 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1431 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1431 times.
1431 if(w->id == wBrang || w->id == wHookshot || w->id == wArrow)
23745 {
23746 int32_t itype, pitem = w->parentitem;
23747 switch(w->id)
23748 {
23749 case wBrang: itype = itype_brang; break;
23750 case wArrow: itype = itype_arrow; break;
23751 case wHookshot:
23752 itype = (w->family_class == itype_switchhook ? itype_switchhook :itype_hookshot);
23753 break;
23754 }
23755 if(pitem < 0) pitem = current_item_id(itype);
23756 if(w->id == wHookshot && w->family_class == itype_switchhook && (itemsbuf[pitem].flags & ITEM_FLAG9))
23757 { //Swap with item
23758 for(int32_t j=0; j<items.Count(); j++)
23759 {
23760 if(items.spr(j)->hit(w))
23761 {
23762 item *theItem = ((item*)items.spr(j));
23763 bool priced = theItem->PriceIndex >-1;
23764 bool isKey = itemsbuf[theItem->id].family==itype_key||itemsbuf[theItem->id].family==itype_lkey;
23765 if(!theItem->fallclk && !theItem->drownclk && ((theItem->pickup & ipTIMER && theItem->clk2 >= 32)
23766 || (((itemsbuf[w->parentitem].flags & ITEM_FLAG4)||(theItem->pickup & ipCANGRAB)||((itemsbuf[w->parentitem].flags & ITEM_FLAG7)&&isKey)) && !priced && !(theItem->pickup & ipDUMMY))))
23767 {
23768 if(!Hero.switchhookclk)
23769 {
23770 hooked_combopos = -1;
23771 hooked_layerbits = 0;
23772 switching_object = theItem;
23773 theItem->switch_hooked = true;
23774 w->misc = 2;
23775 w->step = 0;
23776 theItem->clk2=256;
23777 Hero.doSwitchHook(game->get_switchhookstyle());
23778 if(QMisc.miscsfx[sfxSWITCHED])
23779 sfx(QMisc.miscsfx[sfxSWITCHED],int32_t(w->x));
23780 }
23781 }
23782 }
23783 }
23784 }
23785 else if((w->id==wArrow&&itemsbuf[pitem].flags & ITEM_FLAG2)||(w->id!=wArrow&&!(itemsbuf[pitem].flags & ITEM_FLAG5)))//An arrow with "Picks up items" or a BRang/HShot without "Drags items"
23786 {
23787 for(int32_t j=0; j<items.Count(); j++)
23788 {
23789 if(items.spr(j)->hit(w))
23790 {
23791 item *theItem = ((item*)items.spr(j));
23792 bool priced = theItem->PriceIndex >-1;
23793 bool isKey = itemsbuf[theItem->id].family==itype_key||itemsbuf[theItem->id].family==itype_lkey;
23794 if(!theItem->fallclk && !theItem->drownclk && ((theItem->pickup & ipTIMER && theItem->clk2 >= 32)
23795 || (((itemsbuf[pitem].flags & ITEM_FLAG4)||(theItem->pickup & ipCANGRAB)||((itemsbuf[pitem].flags & ITEM_FLAG7)&&isKey))&& !priced)))
23796 {
23797 if(itemsbuf[theItem->id].collect_script)
23798 {
23799 ZScriptVersion::RunScript(SCRIPT_ITEM, itemsbuf[theItem->id].collect_script, theItem->id & 0xFFF);
23800 }
23801
23802 Hero.checkitems(j);
23803 }
23804 }
23805 }
23806 }
23807 else if(w->id!=wArrow) //A BRang/HShot with "Drags Items"
23808 {
23809 for(int32_t j=0; j<items.Count(); j++)
23810 {
23811 if(items.spr(j)->hit(w))
23812 {
23813 item *theItem = ((item*)items.spr(j));
23814 bool priced = theItem->PriceIndex >-1;
23815 bool isKey = itemsbuf[theItem->id].family==itype_key||itemsbuf[theItem->id].family==itype_lkey;
23816 if(!theItem->fallclk && !theItem->drownclk && ((theItem->pickup & ipTIMER && theItem->clk2 >= 32)
23817 || (((itemsbuf[pitem].flags & ITEM_FLAG4)||(theItem->pickup & ipCANGRAB)||((itemsbuf[pitem].flags & ITEM_FLAG7)&&isKey)) && !priced && !(theItem->pickup & ipDUMMY))))
23818 {
23819 int32_t pickup = theItem->pickup;
23820 int32_t id2 = theItem->id;
23821 int32_t pstr = theItem->pstring;
23822 int32_t pstr_flags = theItem->pickup_string_flags;
23823
23824 std::vector<int32_t> &ev = FFCore.eventData;
23825 ev.clear();
23826 ev.push_back(id2*10000);
23827 ev.push_back(pickup*10000);
23828 ev.push_back(pstr*10000);
23829 ev.push_back(pstr_flags*10000);
23830 ev.push_back(0);
23831 ev.push_back(theItem->getUID());
23832 ev.push_back(GENEVT_ICTYPE_RANGED_DRAG*10000);
23833 ev.push_back(w->getUID());
23834
23835 throwGenScriptEvent(GENSCR_EVENT_COLLECT_ITEM);
23836 bool nullify = ev[4] != 0;
23837 if(nullify) continue;
23838 if(w->id == wBrang)
23839 {
23840 w->onhit(false);
23841 }
23842
23843 if(w->dragging==-1)
23844 {
23845 w->dead=1;
23846 theItem->clk2=256;
23847 w->dragging=j;
23848 theItem->is_dragged = true;
23849 }
23850 }
23851 }
23852 }
23853 }
23854 }
23855 1431 }
23856 4089 }
23857 23254 }
23858
23859 23254 void dragging_item()
23860 {
23861
2/2
✓ Branch 0 taken 4227 times.
✓ Branch 1 taken 23254 times.
27481 for(int32_t i=0; i<Lwpns.Count(); i++)
23862 {
23863 4227 weapon *w = (weapon*)Lwpns.spr(i);
23864
23865
2/4
✓ Branch 0 taken 4227 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4227 times.
✗ Branch 3 not taken.
4227 if((w->id == wBrang || w->id==wHookshot)&&itemsbuf[w->parentitem].flags & ITEM_FLAG5)//ITEM_FLAG5 is a port for qr_Z3BRANG_HSHOT
23866 {
23867 if(w->dragging>=0 && w->dragging<items.Count())
23868 {
23869 item* dragItem = (item*)items.spr(w->dragging);
23870 dragItem->x=w->x;
23871 dragItem->y=w->y;
23872
23873 // Drag the Fairy enemy as well as the Fairy item
23874 int32_t id = dragItem->id;
23875
23876 if(itemsbuf[id].family ==itype_fairy && itemsbuf[id].misc3)
23877 {
23878 movefairynew2(w->x,w->y,*dragItem);
23879 }
23880 }
23881 }
23882 4227 }
23883 23254 }
23884
23885 1 int32_t more_carried_items()
23886 {
23887 1 int32_t hasmorecarries = 0;
23888
23889
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for(int32_t i=0; i<items.Count(); i++)
23890 {
23891
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(((item*)items.spr(i))->pickup & ipENEMY)
23892 {
23893 1 hasmorecarries++;
23894 1 }
23895 1 }
23896
23897 1 return hasmorecarries;
23898 }
23899
23900 // messy code to do the enemy-carrying-the-item thing
23901 23254 void roaming_item()
23902 {
23903
4/4
✓ Branch 0 taken 328 times.
✓ Branch 1 taken 22926 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 327 times.
23254 if(!(hasitem&(4|2)) || !loaded_enemies)
23904 22927 return;
23905
23906 // All enemies already dead upon entering a room?
23907
1/2
✓ Branch 0 taken 327 times.
✗ Branch 1 not taken.
327 if(guys.Count()==0)
23908 {
23909 return;
23910 }
23911
23912 // Lost track of the carrier?
23913
3/6
✓ Branch 0 taken 327 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 327 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 327 times.
✗ Branch 5 not taken.
327 if(guycarryingitem<0 || guycarryingitem>=guys.Count() ||
23914 327 !((enemy*)guys.spr(guycarryingitem))->itemguy)
23915 {
23916 guycarryingitem=-1;
23917 for(int32_t j=0; j<guys.Count(); j++)
23918 {
23919 if(((enemy*)guys.spr(j))->itemguy)
23920 {
23921 guycarryingitem=j;
23922 break;
23923 }
23924 }
23925 }
23926
23927
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 1 times.
327 if(hasitem&4)
23928 {
23929 1 guycarryingitem = -1;
23930
23931
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 for(int32_t i=0; i<guys.Count(); i++)
23932 {
23933
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 if(((enemy*)guys.spr(i))->itemguy)
23934 {
23935 1 guycarryingitem = i;
23936 1 }
23937 5 }
23938
23939
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(guycarryingitem == -1) //This happens when "default enemies" such as
23940 {
23941 return; //eSHOOTFBALL are alive but enemies from the list
23942 } //are not. Defer to HeroClass::checkspecial().
23943
23944 1 int32_t Item=tmpscr->item;
23945
23946 1 hasitem &= ~4;
23947
23948
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if((!getmapflag(mITEM) || (tmpscr->flags9&fITEMRETURN)) && (tmpscr->hasitem != 0))
23949 {
23950 2 additem(0,0,Item,ipENEMY+ipONETIME+ipBIGRANGE
23951
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 + (((tmpscr->flags3&fHOLDITEM) || (itemsbuf[Item].family==itype_triforcepiece)) ? ipHOLDUP : 0)
23952 );
23953 1 hasitem |= 2;
23954 1 }
23955 else
23956 {
23957 return;
23958 }
23959 1 }
23960
23961
2/2
✓ Branch 0 taken 327 times.
✓ Branch 1 taken 327 times.
654 for(int32_t i=0; i<items.Count(); i++)
23962 {
23963
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 327 times.
327 if(((item*)items.spr(i))->pickup&ipENEMY)
23964 {
23965
1/2
✓ Branch 0 taken 327 times.
✗ Branch 1 not taken.
327 if(get_bit(quest_rules,qr_HIDECARRIEDITEMS))
23966 {
23967 items.spr(i)->x = -128; // Awfully inelegant, innit?
23968 items.spr(i)->y = -128;
23969 }
23970
2/4
✓ Branch 0 taken 327 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 327 times.
327 else if(guycarryingitem>=0 && guycarryingitem<guys.Count())
23971 {
23972
1/2
✓ Branch 0 taken 327 times.
✗ Branch 1 not taken.
327 if (!get_bit(quest_rules, qr_BROKEN_ITEM_CARRYING))
23973 {
23974 if (get_bit(quest_rules, qr_ENEMY_DROPS_USE_HITOFFSETS))
23975 {
23976 items.spr(i)->x = guys.spr(guycarryingitem)->x+guys.spr(guycarryingitem)->hxofs+(guys.spr(guycarryingitem)->hxsz/2)-8;
23977 items.spr(i)->y = guys.spr(guycarryingitem)->y+guys.spr(guycarryingitem)->hyofs+(guys.spr(guycarryingitem)->hysz/2)-10;
23978 }
23979 else
23980 {
23981 if(guys.spr(guycarryingitem)->extend >= 3)
23982 {
23983 items.spr(i)->x = guys.spr(guycarryingitem)->x+(guys.spr(guycarryingitem)->txsz-1)*8;
23984 items.spr(i)->y = guys.spr(guycarryingitem)->y-2+(guys.spr(guycarryingitem)->tysz-1)*8;
23985 }
23986 else
23987 {
23988 items.spr(i)->x = guys.spr(guycarryingitem)->x;
23989 items.spr(i)->y = guys.spr(guycarryingitem)->y - 2;
23990 }
23991 }
23992 items.spr(i)->z = guys.spr(guycarryingitem)->z;
23993 items.spr(i)->fakez = guys.spr(guycarryingitem)->fakez;
23994 }
23995 else
23996 {
23997 327 items.spr(i)->x = guys.spr(guycarryingitem)->x;
23998 327 items.spr(i)->y = guys.spr(guycarryingitem)->y - 2;
23999 327 items.spr(i)->fakez = guys.spr(guycarryingitem)->fakez;
24000 }
24001 327 }
24002 327 }
24003 327 }
24004 23254 }
24005
24006 bool enemy::IsBigAnim()
24007 {
24008 return (anim == a2FRMB || anim == a4FRM8EYEB || anim == a4FRM4EYEB
24009 || anim == a4FRM8DIRFB || anim == a4FRM4DIRB || anim == a4FRM4DIRFB
24010 || anim == a4FRM8DIRB);
24011 }
24012
24013 const char *old_guy_string[OLDMAXGUYS] =
24014 {
24015 "(None)","Abei","Ama","Merchant","Moblin","Fire","Fairy","Goriya","Zelda","Abei 2","Empty","","","","","","","","","",
24016 // 020
24017 "Octorok (L1, Slow)","Octorok (L2, Slow)","Octorok (L1, Fast)","Octorok (L2, Fast)","Tektite (L1)",
24018 // 025
24019 "Tektite (L2)","Leever (L1)","Leever (L2)","Moblin (L1)","Moblin (L2)",
24020 // 030
24021 "Lynel (L1)","Lynel (L2)","Peahat (L1)","Zora","Rock",
24022 // 035
24023 "Ghini (L1, Normal)","Ghini (L1, Phantom)","Armos","Keese (CSet 7)","Keese (CSet 8)",
24024 // 040
24025 "Keese (CSet 9)","Stalfos (L1)","Gel (L1, Normal)","Zol (L1, Normal)","Rope (L1)",
24026 // 045
24027 "Goriya (L1)","Goriya (L2)","Trap (4-Way)","Wall Master","Darknut (L1)",
24028 // 050
24029 "Darknut (L2)","Bubble (Sword, Temporary Disabling)","Vire (Normal)","Like Like","Gibdo",
24030 // 055
24031 "Pols Voice (Arrow)","Wizzrobe (Teleporting)","Wizzrobe (Floating)","Aquamentus (Facing Left)","Moldorm",
24032 // 060
24033 "Dodongo","Manhandla (L1)","Gleeok (1 Head)","Gleeok (2 Heads)","Gleeok (3 Heads)",
24034 // 065
24035 "Gleeok (4 Heads)","Digdogger (1 Kid)","Digdogger (3 Kids)","Digdogger Kid (1)","Digdogger Kid (2)",
24036 // 070
24037 "Digdogger Kid (3)","Digdogger Kid (4)","Gohma (L1)","Gohma (L2)","Lanmola (L1)",
24038 // 075
24039 "Lanmola (L2)","Patra (L1, Big Circle)","Patra (L1, Oval)","Ganon","Stalfos (L2)",
24040 // 080
24041 "Rope (L2)","Bubble (Sword, Permanent Disabling)","Bubble (Sword, Re-enabling)","Shooter (Fireball)","Item Fairy ",
24042 // 085
24043 "Fire","Octorok (Magic)", "Darknut (Death Knight)", "Gel (L1, Tribble)", "Zol (L1, Tribble)",
24044 // 090
24045 "Keese (Tribble)", "Vire (Tribble)", "Darknut (Splitting)", "Aquamentus (Facing Right)", "Manhandla (L2)",
24046 // 095
24047 "Trap (Horizontal, Line of Sight)", "Trap (Vertical, Line of Sight)", "Trap (Horizontal, Constant)", "Trap (Vertical, Constant)", "Wizzrobe (Fire)",
24048 // 100
24049 "Wizzrobe (Wind)", "Ceiling Master ", "Floor Master ", "Patra (BS Zelda)", "Patra (L2)",
24050 // 105
24051 "Patra (L3)", "Bat", "Wizzrobe (Bat)", "Wizzrobe (Bat 2) ", "Gleeok (Fire, 1 Head)",
24052 // 110
24053 "Gleeok (Fire, 2 Heads)", "Gleeok (Fire, 3 Heads)","Gleeok (Fire, 4 Heads)", "Wizzrobe (Mirror)", "Dodongo (BS Zelda)",
24054 // 115
24055 "Dodongo (Fire) ","Trigger", "Bubble (Item, Temporary Disabling)", "Bubble (Item, Permanent Disabling)", "Bubble (Item, Re-enabling)",
24056 // 120
24057 "Stalfos (L3)", "Gohma (L3)", "Gohma (L4)", "NPC 1 (Standing) ", "NPC 2 (Standing) ",
24058 // 125
24059 "NPC 3 (Standing) ", "NPC 4 (Standing) ", "NPC 5 (Standing) ", "NPC 6 (Standing) ", "NPC 1 (Walking) ",
24060 // 130
24061 "NPC 2 (Walking) ", "NPC 3 (Walking) ", "NPC 4 (Walking) ", "NPC 5 (Walking) ", "NPC 6 (Walking) ",
24062 // 135
24063 "Boulder", "Goriya (L3)", "Leever (L3)", "Octorok (L3, Slow)", "Octorok (L3, Fast)",
24064 // 140
24065 "Octorok (L4, Slow)", "Octorok (L4, Fast)", "Trap (8-Way) ", "Trap (Diagonal) ", "Trap (/, Constant) ",
24066 // 145
24067 "Trap (/, Line of Sight) ", "Trap (\\, Constant) ", "Trap (\\, Line of Sight) ", "Trap (CW, Constant) ", "Trap (CW, Line of Sight) ",
24068 // 150
24069 "Trap (CCW, Constant) ", "Trap (CCW, Line of Sight) ", "Wizzrobe (Summoner)", "Wizzrobe (Ice) ", "Shooter (Magic)",
24070 // 155
24071 "Shooter (Rock)", "Shooter (Spear)", "Shooter (Sword)", "Shooter (Fire)", "Shooter (Fire 2)",
24072 // 160
24073 "Bombchu", "Gel (L2, Normal)", "Zol (L2, Normal)", "Gel (L2, Tribble)", "Zol (L2, Tribble)",
24074 // 165
24075 "Tektite (L3) ", "Spinning Tile (Combo)", "Spinning Tile (Enemy Sprite)", "Lynel (L3) ", "Peahat (L2) ",
24076 // 170
24077 "Pols Voice (Magic) ", "Pols Voice (Whistle) ", "Darknut (Mirror) ", "Ghini (L2, Fire) ", "Ghini (L2, Magic) ",
24078 // 175
24079 "Grappler Bug (HP) ", "Grappler Bug (MP) "
24080 };
24081
24082 /*** end of guys.cc ***/
24083
24084